From 8d7da08f6f0095510c359df4dc2d433a9022cf67 Mon Sep 17 00:00:00 2001 From: Matthias Schmidt Date: Mon, 15 Apr 2019 18:01:54 +0200 Subject: [PATCH] Show exception file and line in exception dialog (#2895) * Show exception file and line in exception dialog Close #2894 * Add missing semicolon See #2895 --- .../js/WoltLabSuite/Core/Ajax/Request.js | 8 +- .../files/lib/action/TAJAXException.class.php | 75 ++++++++++++++++--- .../system/exception/AJAXException.class.php | 36 ++++++--- 3 files changed, 96 insertions(+), 23 deletions(-) diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js index 04f537cb09..85f8cebfa2 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Request.js @@ -313,8 +313,12 @@ define(['Core', 'Language', 'Dom/ChangeListener', 'Dom/Util', 'Ui/Dialog', 'Wolt var message = ''; if (data !== null) { - if (data.stacktrace) details = '

Stacktrace:

' + data.stacktrace + '

'; - else if (data.exceptionID) details = '

Exception ID: ' + data.exceptionID + '

'; + if (data.file && data.line) { + details += '

File:

' + data.file + ' in line ' + data.line + '

'; + } + + if (data.stacktrace) details += '

Stacktrace:

' + data.stacktrace + '

'; + else if (data.exceptionID) details += '

Exception ID: ' + data.exceptionID + '

'; message = data.message; diff --git a/wcfsetup/install/files/lib/action/TAJAXException.class.php b/wcfsetup/install/files/lib/action/TAJAXException.class.php index adf836fa0a..51ceddca00 100644 --- a/wcfsetup/install/files/lib/action/TAJAXException.class.php +++ b/wcfsetup/install/files/lib/action/TAJAXException.class.php @@ -16,7 +16,7 @@ use wcf\system\WCF; * @copyright 2001-2019 WoltLab GmbH * @license GNU Lesser General Public License * @package WoltLabSuite\Core\Action - * @since 5.2 + * @since 5.2 */ trait TAJAXException { /** @@ -29,36 +29,87 @@ trait TAJAXException { */ protected function throwException($e) { if ($e instanceof InvalidSecurityTokenException) { - throw new AJAXException(WCF::getLanguage()->getDynamicVariable('wcf.ajax.error.sessionExpired'), AJAXException::SESSION_EXPIRED, $e->getTraceAsString()); + throw new AJAXException( + WCF::getLanguage()->getDynamicVariable('wcf.ajax.error.sessionExpired'), + AJAXException::SESSION_EXPIRED, + $e->getTraceAsString(), + [ + 'file' => $e->getFile(), + 'line' => $e->getLine() + ] + ); } else if ($e instanceof PermissionDeniedException) { - throw new AJAXException(WCF::getLanguage()->getDynamicVariable('wcf.ajax.error.permissionDenied'), AJAXException::INSUFFICIENT_PERMISSIONS, $e->getTraceAsString()); + throw new AJAXException( + WCF::getLanguage()->getDynamicVariable('wcf.ajax.error.permissionDenied'), + AJAXException::INSUFFICIENT_PERMISSIONS, + $e->getTraceAsString(), + [ + 'file' => $e->getFile(), + 'line' => $e->getLine() + ] + ); } else if ($e instanceof IllegalLinkException) { - throw new AJAXException(WCF::getLanguage()->get('wcf.ajax.error.illegalLink'), AJAXException::ILLEGAL_LINK, $e->getTraceAsString()); + throw new AJAXException( + WCF::getLanguage()->get('wcf.ajax.error.illegalLink'), + AJAXException::ILLEGAL_LINK, + $e->getTraceAsString(), + [ + 'file' => $e->getFile(), + 'line' => $e->getLine() + ] + ); } else if ($e instanceof UserInputException) { // repackage as ValidationActionException $exception = new ValidateActionException($e->getField(), $e->getType(), $e->getVariables()); - throw new AJAXException($exception->getMessage(), AJAXException::BAD_PARAMETERS, $e->getTraceAsString(), [ - 'errorMessage' => $exception->getMessage(), - 'errorType' => $e->getType(), - 'fieldName' => $exception->getFieldName(), - 'realErrorMessage' => $exception->getErrorMessage() - ]); + throw new AJAXException( + $exception->getMessage(), + AJAXException::BAD_PARAMETERS, + $e->getTraceAsString(), + [ + 'errorMessage' => $exception->getMessage(), + 'errorType' => $e->getType(), + 'file' => $e->getFile(), + 'fieldName' => $e->getFieldName(), + 'line' => $e->getLine(), + 'realErrorMessage' => $exception->getErrorMessage() + ] + ); } else if ($e instanceof ValidateActionException) { throw new AJAXException($e->getMessage(), AJAXException::BAD_PARAMETERS, $e->getTraceAsString(), [ 'errorMessage' => $e->getMessage(), + 'file' => $e->getFile(), 'fieldName' => $e->getFieldName(), + 'line' => $e->getLine(), 'realErrorMessage' => $e->getErrorMessage() ]); } else if ($e instanceof NamedUserException) { - throw new AJAXException($e->getMessage(), AJAXException::BAD_PARAMETERS, $e->getTraceAsString()); + throw new AJAXException( + $e->getMessage(), + AJAXException::BAD_PARAMETERS, + $e->getTraceAsString(), + [ + 'file' => $e->getFile(), + 'line' => $e->getLine() + ] + ); } else { - throw new AJAXException($e->getMessage(), AJAXException::INTERNAL_ERROR, $e->getTraceAsString(), [], \wcf\functions\exception\logThrowable($e), $e->getPrevious()); + throw new AJAXException( + $e->getMessage(), + AJAXException::INTERNAL_ERROR, + $e->getTraceAsString(), + [ + 'file' => $e->getFile(), + 'line' => $e->getLine() + ], + \wcf\functions\exception\logThrowable($e), + $e->getPrevious() + ); } } } diff --git a/wcfsetup/install/files/lib/system/exception/AJAXException.class.php b/wcfsetup/install/files/lib/system/exception/AJAXException.class.php index ad6750de06..3905a2b152 100644 --- a/wcfsetup/install/files/lib/system/exception/AJAXException.class.php +++ b/wcfsetup/install/files/lib/system/exception/AJAXException.class.php @@ -62,13 +62,6 @@ class AJAXException extends LoggedException { public function __construct($message, $errorType = self::INTERNAL_ERROR, $stacktrace = null, $returnValues = [], $exceptionID = '', $previous = null) { if ($stacktrace === null) $stacktrace = $this->getTraceAsString(); - $responseData = [ - 'code' => $errorType, - 'message' => $message, - 'previous' => [], - 'returnValues' => $returnValues - ]; - // include a stacktrace if: // - debug mode is enabled or // - within ACP and a SystemException was thrown @@ -84,11 +77,36 @@ class AJAXException extends LoggedException { $includeStacktrace = WCF::debugModeIsEnabled(); } - if ($includeStacktrace) { - $responseData['stacktrace'] = nl2br($stacktrace, false); + // extract file and line in which exception was thrown and only include it + // if stacktrace is also included + $file = $line = null; + if (isset($returnValues['file'])) { + if ($includeStacktrace) { + $file = $returnValues['file']; + } + + unset($returnValues['file']); + } + if (isset($returnValues['line'])) { + if ($includeStacktrace) { + $line = $returnValues['line']; + } + + unset($returnValues['line']); } + $responseData = [ + 'code' => $errorType, + 'file' => $file, + 'line' => $line, + 'message' => $message, + 'previous' => [], + 'returnValues' => $returnValues + ]; + if ($includeStacktrace) { + $responseData['stacktrace'] = nl2br($stacktrace, false); + while ($previous) { $data = ['message' => $previous->getMessage()]; $data['stacktrace'] = nl2br($previous->getTraceAsString(), false); -- 2.20.1