Skip to content

Commit 0582888

Browse files
Init/Error: Improve error handling in error.php
This commit improves the global error handling in `error.php`: 1. Remove building a global template from `tpl.main.html` since it only contains one placeholder (see 2b8eafc) and provides no added value 2. Ensure a proper HTTP 500 status code is sent for normal error handling 3. Ensure a proper HTTP 500 status code is sent if an unexpected error occurs while rendering the error page 4. Log errors to `error_log` with minimal user-facing output, including an incident ID, timestamp, and message
1 parent 1381b15 commit 0582888

File tree

1 file changed

+58
-16
lines changed

1 file changed

+58
-16
lines changed

components/ILIAS/Init/resources/error.php

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,73 @@
1818

1919
declare(strict_types=1);
2020

21+
namespace ILIAS\Init;
22+
2123
try {
2224
require_once '../vendor/composer/vendor/autoload.php';
23-
ilInitialisation::initILIAS();
25+
\ilInitialisation::initILIAS();
26+
2427
$DIC->globalScreen()->tool()->context()->claim()->external();
25-
$local_tpl = new ilGlobalTemplate("tpl.main.html", true, true);
26-
$local_tpl->addBlockFile("CONTENT", "content", "tpl.error.html");
27-
$lng->loadLanguageModule("error");
28-
// #13515 - link back to "system" [see ilWebAccessChecker::sendError()]
29-
$nd = $tree->getNodeData(ROOT_FOLDER_ID);
28+
29+
$lng->loadLanguageModule('error');
3030
$txt = $lng->txt('error_back_to_repository');
31-
$local_tpl->SetCurrentBlock("ErrorLink");
32-
$local_tpl->SetVariable("TXT_LINK", $txt);
33-
$local_tpl->SetVariable("LINK", ilUtil::secureUrl(ILIAS_HTTP_PATH . '/ilias.php?baseClass=ilRepositoryGUI&client_id=' . CLIENT_ID));
34-
$local_tpl->ParseCurrentBlock();
3531

36-
ilSession::clear("referer");
37-
ilSession::clear("message");
32+
$local_tpl = new \ilGlobalTemplate('tpl.error.html', true, true);
33+
$local_tpl->setCurrentBlock('ErrorLink');
34+
$local_tpl->setVariable('TXT_LINK', $txt);
35+
$local_tpl->setVariable('LINK', \ilUtil::secureUrl(ILIAS_HTTP_PATH . '/ilias.php?baseClass=ilRepositoryGUI'));
36+
$local_tpl->parseCurrentBlock();
37+
38+
\ilSession::clear('referer');
39+
\ilSession::clear('message');
40+
41+
$DIC->http()->saveResponse(
42+
$DIC->http()
43+
->response()
44+
->withStatus(500)
45+
->withHeader(\ILIAS\HTTP\Response\ResponseHeader::CONTENT_TYPE, 'text/html')
46+
);
47+
3848
$tpl->setContent($local_tpl->get());
3949
$tpl->printToStdout();
40-
} catch (Exception $e) {
41-
if (defined('DEVMODE') && DEVMODE) {
50+
51+
$DIC->http()->close();
52+
} catch (\Throwable $e) {
53+
if (\defined('DEVMODE') && DEVMODE) {
4254
throw $e;
4355
}
4456

45-
if (!($e instanceof \PDOException)) {
46-
die($e->getMessage());
57+
/*
58+
* Since we are already in the `error.php` and an unexpected error occurred, we should not rely on the $DIC or any
59+
* other components here and use "Vanilla PHP" instead to handle the error.
60+
*/
61+
if (!headers_sent()) {
62+
http_response_code(500);
63+
header('Content-Type: text/plain; charset=UTF-8');
64+
}
65+
66+
$incident_id = session_id() . '_' . (new \Random\Randomizer())->getInt(1, 9999);
67+
$timestamp = (new \DateTimeImmutable())->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d\TH:i:s\Z');
68+
69+
echo "Internal Server Error\n";
70+
echo "Incident: $incident_id\n";
71+
echo "Timestamp: $timestamp\n";
72+
if ($e instanceof \PDOException) {
73+
echo "Message: A database error occurred. Please contact the system administrator with the incident id.\n";
74+
} else {
75+
echo "Message: {$e->getMessage()}\n";
4776
}
77+
78+
error_log(\sprintf(
79+
"[%s] INCIDENT %s — Uncaught %s: %s in %s:%d\nStack trace:\n%s\n",
80+
$timestamp,
81+
$incident_id,
82+
\get_class($e),
83+
$e->getMessage(),
84+
$e->getFile(),
85+
$e->getLine(),
86+
$e->getTraceAsString()
87+
));
88+
89+
exit(1);
4890
}

0 commit comments

Comments
 (0)