【发布时间】:2019-11-12 22:00:16
【问题描述】:
我正在开发一个 PHP 项目,我在该项目中使用 Monolog 捕获异常并记录错误,并返回一个用户友好的页面作为响应。
该项目目前处于婴儿阶段,所以我只是使用 Monolog 的 StreamHandler 类将错误记录到一个文件中,该文件位于公众无法访问的应用目录中,随着我的进展,我意识到如果有 IO 这可能会失败某种错误,因此我还将记录到数据库(可能是 ElasticSearch)并通过电子邮件将严重错误发送给管理员。
当我使用StreamHandler 时,我可以看到如果无法打开文件,它会引发异常。
现在,我应该如何处理这种异常情况,如果日志记录机制本身失败,我应该如何记录它?
我可以让另一个记录器处理异常,该记录器会在这种危急情况下发送电子邮件,但同样,我该如何处理邮件程序抛出的异常?
我认为该页面将充满太多的 try-catch 块,记录器分布在整个页面中,这看起来非常难看。
是否有一个优雅、干净的解决方案,不涉及在大型项目中使用的太多嵌套的 try-catch 块? (也欢迎不受欢迎的意见)
这里有一些代码供参考:
try
{
$routes = require_once(__DIR__.'/Routes.php');
$router = new RouteFactory($routes, $request, \Skletter\View\ErrorPages::class);
$router->buildPaths('Skletter\Controller\\', 'Skletter\View\\');
$app = new Application($injector);
$app->run($request, $router);
}
catch (InjectionException | InvalidErrorPage | NoHandlerSpecifiedException $e)
{
$log = new Logger('Resolution');
try
{
$log->pushHandler(new StreamHandler(__DIR__ . '/../app/logs/error.log', Logger::CRITICAL));
$log->addCritical($e->getMessage(),
array(
'Stack Trace' => $e->getTraceAsString()
));
}
catch (Exception $e)
{
echo "No access to log file: ". $e->getMessage();
// Should I handle this exception by pushing to db or emailing?
// Can possibly introduce another nested try-catch block
}
finally
{
/**
* @var \Skletter\View\ErrorPageView $errorPage
*/
$errorPage = $injector->make(\Skletter\View\ErrorPages::class);
$errorPage->internalError($request)->send();
}
}
【问题讨论】:
-
你用的是什么版本的PHP?
-
@maximfedorov PHP 7.3
标签: php exception logging try-catch