mirror of
https://github.com/flarum/framework.git
synced 2024-11-26 02:10:09 +08:00
Hide boot error (#2633)
Completely redact boot error unless debug mode or display_errors is enabled. Attempt to use Flarum log file when possible. Fixes #2290
This commit is contained in:
parent
a4ba1f890c
commit
185abf05b7
|
@ -9,6 +9,7 @@
|
|||
|
||||
namespace Flarum\Http;
|
||||
|
||||
use Flarum\Foundation\ErrorHandling\LogReporter;
|
||||
use Flarum\Foundation\SiteInterface;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\ServerRequest;
|
||||
|
@ -16,6 +17,7 @@ use Laminas\Diactoros\ServerRequestFactory;
|
|||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||
use Laminas\HttpHandlerRunner\RequestHandlerRunner;
|
||||
use Laminas\Stratigility\Middleware\ErrorResponseGenerator;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
class Server
|
||||
|
@ -55,26 +57,70 @@ class Server
|
|||
try {
|
||||
return $this->site->bootApp()->getRequestHandler();
|
||||
} catch (Throwable $e) {
|
||||
exit($this->formatBootException($e));
|
||||
// Apply response code first so whatever happens, it's set before anything is printed
|
||||
http_response_code(500);
|
||||
|
||||
try {
|
||||
$this->cleanBootExceptionLog($e);
|
||||
} catch (Throwable $e) {
|
||||
// Ignore errors in logger. The important goal is to log the original error
|
||||
}
|
||||
|
||||
$this->fallbackBootExceptionLog($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the most relevant information about an early exception.
|
||||
* Attempt to log the boot exception in a clean way and stop the script execution.
|
||||
* This means looking for debug mode and/or our normal error logger.
|
||||
* There is always a risk for this to fail,
|
||||
* for example if the container bindings aren't present
|
||||
* or if there is a filesystem error.
|
||||
* @param Throwable $error
|
||||
*/
|
||||
private function formatBootException(Throwable $error): string
|
||||
private function cleanBootExceptionLog(Throwable $error)
|
||||
{
|
||||
$message = $error->getMessage();
|
||||
$file = $error->getFile();
|
||||
$line = $error->getLine();
|
||||
$type = get_class($error);
|
||||
if (app()->has('flarum.config') && app('flarum.config')->inDebugMode()) {
|
||||
// If the application booted far enough for the config to be available, we will check for debug mode
|
||||
// Since the config is loaded very early, it is very likely to be available from the container
|
||||
$message = $error->getMessage();
|
||||
$file = $error->getFile();
|
||||
$line = $error->getLine();
|
||||
$type = get_class($error);
|
||||
|
||||
return <<<ERROR
|
||||
echo <<<ERROR
|
||||
Flarum encountered a boot error ($type)<br />
|
||||
<b>$message</b><br />
|
||||
thrown in <b>$file</b> on line <b>$line</b>
|
||||
|
||||
<pre>$error</pre>
|
||||
ERROR;
|
||||
exit(1);
|
||||
} elseif (app()->has(LoggerInterface::class)) {
|
||||
// If the application booted far enough for the logger to be available, we will log the error there
|
||||
// Considering most boot errors are related to database or extensions, the logger should already be loaded
|
||||
// We check for LoggerInterface binding because it's a constructor dependency of LogReporter,
|
||||
// then instantiate LogReporter through the container for automatic dependency injection
|
||||
app(LogReporter::class)->report($error);
|
||||
|
||||
echo 'Flarum encountered a boot error. Details have been logged to the Flarum log file.';
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the clean logging doesn't work, then we have a last opportunity.
|
||||
* Here we need to be extra careful not to include anything that might be sensitive on the page.
|
||||
* @param Throwable $error
|
||||
* @throws Throwable
|
||||
*/
|
||||
private function fallbackBootExceptionLog(Throwable $error)
|
||||
{
|
||||
echo 'Flarum encountered a boot error. Details have been logged to the system PHP log file.<br />';
|
||||
|
||||
// Throwing the exception ensures it will be visible with PHP display_errors=On
|
||||
// but invisible if that feature is turned off
|
||||
// PHP will also automatically choose a valid place to log it based on the system settings
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user