* Make the HTML error message prettier, with a nice red box and
instructions to modify LocalSettings.php hidden in an HTML comment.
* Show the exception class name, since that's pretty safe.
* Show a random "log ID" to the user, and also send it to the exception
log, to allow easier log correlation.
* Optionally send backtraces to the error log, enabled by default.
Change-Id: Ie92e46032b3d194c4217119567847a38a53be577
* (bug 22887) Add warning and tracking category for preprocessor errors
* (bug 31704) Allow selection of associated namespace on the watchlist
* (bug 5445) Now remove autoblocks when a user is unblocked.
* (bug 22887) Add warning and tracking category for preprocessor errors
* (bug 31704) Allow selection of associated namespace on the watchlist
* (bug 5445) Now remove autoblocks when a user is unblocked.
+* Added $wgLogExceptionBacktrace, on by default, to allow logging of exception
+ backtraces.
=== Bug fixes in 1.20 ===
* (bug 30245) Use the correct way to construct a log page title.
=== Bug fixes in 1.20 ===
* (bug 30245) Use the correct way to construct a log page title.
*/
$wgShowDBErrorBacktrace = false;
*/
$wgShowDBErrorBacktrace = false;
+/**
+ * If true, send the exception backtrace to the error log
+ */
+$wgLogExceptionBacktrace = true;
+
/**
* Expose backend server host names through the API and various HTML comments
*/
/**
* Expose backend server host names through the API and various HTML comments
*/
* @ingroup Exception
*/
class MWException extends Exception {
* @ingroup Exception
*/
class MWException extends Exception {
/**
* Should the exception use $wgOut to output the error ?
* @return bool
/**
* Should the exception use $wgOut to output the error ?
* @return bool
'</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
"</p>\n";
} else {
'</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
"</p>\n";
} else {
- return "<p>Set <b><tt>\$wgShowExceptionDetails = true;</tt></b> " .
+ return
+ "<div class=\"errorbox\">" .
+ '[' . $this->getLogId() . '] ' .
+ gmdate( 'Y-m-d H:i:s' ) .
+ ": Fatal exception of type " . get_class( $this ) . "</div>\n" .
+ "<!-- Set \$wgShowExceptionDetails = true; " .
"at the bottom of LocalSettings.php to show detailed " .
"at the bottom of LocalSettings.php to show detailed " .
- "debugging information.</p>";
+ "debugging information. -->";
return $this->msg( 'internalerror', "Internal error" );
}
return $this->msg( 'internalerror', "Internal error" );
}
+ function getLogId() {
+ if ( $this->logId === null ) {
+ $this->logId = wfRandomString( 8 );
+ }
+ return $this->logId;
+ }
+
/**
* Return the requested URL and point to file and line number from which the
* exception occured
/**
* Return the requested URL and point to file and line number from which the
* exception occured
function getLogMessage() {
global $wgRequest;
function getLogMessage() {
global $wgRequest;
+ $id = $this->getLogId();
$file = $this->getFile();
$line = $this->getLine();
$message = $this->getMessage();
$file = $this->getFile();
$line = $this->getLine();
$message = $this->getMessage();
- return "$url Exception from line $line of $file: $message";
+ return "[$id] $url Exception from line $line of $file: $message";
}
/** Output the exception report using HTML */
}
/** Output the exception report using HTML */
* It will be either HTML or plain text based on isCommandLine().
*/
function report() {
* It will be either HTML or plain text based on isCommandLine().
*/
function report() {
+ global $wgLogExceptionBacktrace;
$log = $this->getLogMessage();
if ( $log ) {
$log = $this->getLogMessage();
if ( $log ) {
- wfDebugLog( 'exception', $log );
+ if ( $wgLogExceptionBacktrace ) {
+ wfDebugLog( 'exception', $log . "\n" . $this->getTraceAsString() . "\n" );
+ } else {
+ wfDebugLog( 'exception', $log );
+ }
}
if ( defined( 'MW_API' ) ) {
}
if ( defined( 'MW_API' ) ) {