From 70841c5867c4a97311e49be8fbcb1a4841a90406 Mon Sep 17 00:00:00 2001
From: Tim Starling
Date: Tue, 8 May 2012 09:53:58 +1000
Subject: [PATCH] Make $wgShowExceptionDetails=false more feasible for
production
* 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
---
RELEASE-NOTES-1.20 | 2 ++
includes/DefaultSettings.php | 5 +++++
includes/Exception.php | 28 ++++++++++++++++++++++++----
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/RELEASE-NOTES-1.20 b/RELEASE-NOTES-1.20
index 4920509ee9..78c7c95919 100644
--- a/RELEASE-NOTES-1.20
+++ b/RELEASE-NOTES-1.20
@@ -54,6 +54,8 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
* (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.
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index d05f02073d..7084bc6119 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -4141,6 +4141,11 @@ $wgShowExceptionDetails = 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
*/
diff --git a/includes/Exception.php b/includes/Exception.php
index 539d483534..f7b6b964f6 100644
--- a/includes/Exception.php
+++ b/includes/Exception.php
@@ -15,6 +15,8 @@
* @ingroup Exception
*/
class MWException extends Exception {
+ var $logId;
+
/**
* Should the exception use $wgOut to output the error ?
* @return bool
@@ -111,9 +113,14 @@ class MWException extends Exception {
'
Backtrace:
' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
"
\n";
} else {
- return "Set \$wgShowExceptionDetails = true; " .
+ return
+ "
" .
+ '[' . $this->getLogId() . '] ' .
+ gmdate( 'Y-m-d H:i:s' ) .
+ ": Fatal exception of type " . get_class( $this ) . "
\n" .
+ "";
}
}
@@ -142,6 +149,13 @@ class MWException extends Exception {
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
@@ -151,6 +165,7 @@ class MWException extends Exception {
function getLogMessage() {
global $wgRequest;
+ $id = $this->getLogId();
$file = $this->getFile();
$line = $this->getLine();
$message = $this->getMessage();
@@ -164,7 +179,7 @@ class MWException extends Exception {
$url = '[no req]';
}
- 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 */
@@ -198,10 +213,15 @@ class MWException extends Exception {
* It will be either HTML or plain text based on isCommandLine().
*/
function report() {
+ global $wgLogExceptionBacktrace;
$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' ) ) {
--
2.20.1