Skip to content

Commit

Permalink
[Core: Module] Explicitly handle 500 errors properly for various exc…
Browse files Browse the repository at this point in the history
…eption types (#4163)

This fixes a bug where LORIS would sometimes incorrectly show 404 errors when an exception was thrown.

It adds exception handlers for explicit exception types in the Module router and logs them to the error log, while serving a properly decorated 500 error page to the user.
  • Loading branch information
johnsaigle authored and driusan committed Dec 10, 2018
1 parent d386cb3 commit 5fc333c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 4 deletions.
70 changes: 69 additions & 1 deletion php/libraries/Module.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* This file contains a class which encapsulates the concept of a "module"
* in LORIS.
*
* PHP Version 5
* PHP Version 7
*
* @category Main
* @package Loris
Expand All @@ -26,6 +26,12 @@ use \Psr\Http\Message\ResponseInterface;
*/
class Module extends \LORIS\Router\PrefixRouter implements RequestHandlerInterface
{
const GENERIC_500_ERROR = "We're sorry, LORIS has encountered an internal "
. "server error. Please contact your project administrator for more "
. "information.";
const CONFIGURATION_ERROR = "LORIS configuration settings are invalid or "
. "missing and as a result execution cannot proceed. Please contact "
. "your project administrator and/or verify your LORIS configuration.";
protected $name;
protected $dir;

Expand Down Expand Up @@ -277,8 +283,70 @@ class Module extends \LORIS\Router\PrefixRouter implements RequestHandlerInterfa
)
)
);
/* The order of these catch statements matter and should go from
* most to least specific. Otherwise all Exceptions will be caught
* as their more generic parent class which reduces precision.
*/
} catch (\DatabaseException $e) {
error_log($e);
return $this->responseStatus500(
$request,
$user,
self::GENERIC_500_ERROR
);
} catch (\ConfigurationException $e) {
error_log($e);
return $this->responseStatus500(
$request,
$user,
self::CONFIGURATION_ERROR
);
} catch (\LorisException $e) {
error_log($e);
return $this->responseStatus500(
$request,
$user,
self::GENERIC_500_ERROR
);
} catch (\Exception $e) {
error_log($e);
return $this->responseStatus500(
$request,
$user,
self::GENERIC_500_ERROR
);
}

return $page->process($request, $page);
}

/**
* Return a properly-decorated response with status 500. Used to handle
* exceptions thrown within the codebase in a graceful way.
*
* @param ServerRequestInterface $request The request to process.
* @param \User $user The user to decorate the page with.
* @param string $message An error message explaining the
* 500 code to the user.
*
* @return ResponseInterface A properly decorated 500 response.
*/
function responseStatus500(
ServerRequestInterface $request,
\User $user,
string $message
): ResponseInterface {
return (new \LORIS\Middleware\PageDecorationMiddleware(
$user
))->process(
$request,
new \LORIS\Router\NoopResponder(
new \LORIS\Http\Error(
$request,
500,
$message
)
)
);
}
}
4 changes: 1 addition & 3 deletions smarty/templates/500.tpl
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<div class="container">
{foreach from=$error_message item=message}
<h2>{$message}</h2>
{/foreach}
<h3>{$message}</h3>
<div><a href="{$baseurl}">Go to main page</a></div>
</div>

0 comments on commit 5fc333c

Please sign in to comment.