X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2FException.php;h=008be15a383ddb527d4f6e460237f2af9b988ce1;hb=35970fb460060cab9a3984030241987a86146f09;hp=ac98564e2ccc077b3f90a58c5934b23085ea9d90;hpb=cba23cc37e55caded76d2a4c6b6125db4f92e63e;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Exception.php b/includes/Exception.php index ac98564e2c..008be15a38 100644 --- a/includes/Exception.php +++ b/includes/Exception.php @@ -779,6 +779,21 @@ class MWExceptionHandler { return $e->_mwLogId; } + /** + * If the exception occurred in the course of responding to a request, + * returns the requested URL. Otherwise, returns false. + * + * @since 1.23 + * @return string|bool + */ + public static function getURL() { + global $wgRequest; + if ( !isset( $wgRequest ) || $wgRequest instanceof FauxRequest ) { + return false; + } + return $wgRequest->getRequestURL(); + } + /** * Return the requested URL and point to file and line number from which the * exception occurred. @@ -788,23 +803,88 @@ class MWExceptionHandler { * @return string */ public static function getLogMessage( Exception $e ) { - global $wgRequest; - $id = self::getLogId( $e ); $file = $e->getFile(); $line = $e->getLine(); $message = $e->getMessage(); + $url = self::getURL() ?: '[no req]'; - if ( isset( $wgRequest ) && !$wgRequest instanceof FauxRequest ) { - $url = $wgRequest->getRequestURL(); - if ( !$url ) { - $url = '[no URL]'; - } - } else { - $url = '[no req]'; + return "[$id] $url Exception from line $line of $file: $message"; + } + + /** + * Serialize an Exception object to JSON. + * + * The JSON object will have keys 'id', 'file', 'line', 'message', and + * 'url'. These keys map to string values, with the exception of 'line', + * which is a number, and 'url', which may be either a string URL or or + * null if the exception did not occur in the context of serving a web + * request. + * + * If $wgLogExceptionBacktrace is true, it will also have a 'backtrace' + * key, mapped to the array return value of Exception::getTrace, but with + * each element in each frame's "args" array (if set) replaced with the + * argument's class name (if the argument is an object) or type name (if + * the argument is a PHP primitive). + * + * @par Sample JSON record ($wgLogExceptionBacktrace = false): + * @code + * { + * "id": "c41fb419", + * "file": "/var/www/mediawiki/includes/cache/MessageCache.php", + * "line": 704, + * "message": "Non-string key given", + * "url": "/wiki/Main_Page" + * } + * @endcode + * + * @par Sample JSON record ($wgLogExceptionBacktrace = true): + * @code + * { + * "id": "dc457938", + * "file": "/vagrant/mediawiki/includes/cache/MessageCache.php", + * "line": 704, + * "message": "Non-string key given", + * "url": "/wiki/Main_Page", + * "backtrace": [{ + * "file": "/vagrant/mediawiki/extensions/VisualEditor/VisualEditor.hooks.php", + * "line": 80, + * "function": "get", + * "class": "MessageCache", + * "type": "->", + * "args": ["array"] + * }] + * } + * @endcode + * + * @since 1.23 + * @param Exception $e + * @param bool $pretty Add non-significant whitespace to improve readability (default: false). + * @param int $escaping Bitfield consisting of FormatJson::.*_OK class constants. + * @return string|bool: JSON string if successful; false upon failure + */ + public static function jsonSerializeException( Exception $e, $pretty = false, $escaping = 0 ) { + global $wgLogExceptionBacktrace; + + $exceptionData = array( + 'id' => self::getLogId( $e ), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + 'message' => $e->getMessage(), + ); + + // Because MediaWiki is first and foremost a web application, we set a + // 'url' key unconditionally, but set it to null if the exception does + // not occur in the context of a web request, as a way of making that + // fact visible and explicit. + $exceptionData['url'] = self::getURL() ?: null; + + if ( $wgLogExceptionBacktrace ) { + // Argument values may not be serializable, so redact them. + $exceptionData['backtrace'] = self::getRedactedTrace( $e ); } - return "[$id] $url Exception from line $line of $file: $message"; + return FormatJson::encode( $exceptionData, $pretty, $escaping ); } /** @@ -826,7 +906,13 @@ class MWExceptionHandler { } else { wfDebugLog( 'exception', $log ); } + + $json = self::jsonSerializeException( $e, false, FormatJson::ALL_OK ); + if ( $json !== false ) { + wfDebugLog( 'exception-json', $json, false ); + } } + } }