我有一个自定义异常(在其他自定义异常中进一步扩展)。我的项目需要记录发生的所有 customExceptions(及其所有后代)。我有一个可以记录 customException(和其他任何东西)的记录器。一种方法是在异常处理时显式记录异常,如下所示。
try{
//some exception occur
}
catch(customeException $e)
{
$log->logException($e);
$e->showMessage(); // or do anything that we have to do with the error.
}
因为我们正在记录所有的 customExceptions,我能想到的另一种方法是更新 customException 构造函数并在构造函数内部记录异常。通过这种方式,它确保记录所有 customException。但是,如果我们走这条路,我的问题是:
- 如何将记录器注入(inject) customException?
- 是否会违反 SRP 原则?
- 它会被视为 OOP 意义上的不良做法,还是这方面的最佳做法是什么?
最佳答案
我认为将记录器注入(inject) CustomException 是不正确的,因为(如您所指)它破坏了 SRP 并增加了异常类的复杂性。
我建议您将 Exception 与 ExceptionHandler 分开。异常类应该只包含关于“什么(和哪里)出了问题”的信息。 ExceptionHandler 负责记录异常(并在需要时做一些其他处理异常的工作)。
因此您可以设置一个全局 ExceptionHandler
(使用 set_exception_handler 和 set_error_handler 或一些基于框架的异常处理机制,如 symfony's ExceptionListener ),它将捕获所有未处理的异常。
<?php
class ExceptionHandler {
/**
* @var Logger
*/
private $logger;
public function __construct(Logger $logger)
{
$this->logger = $logger;
}
public function handle(Throwable $e)
{
$this->logger->logException($e);
}
}
在应用程序代码中,您仍然可以抛出和捕获异常。我认为有 4 种常见情况。
完全可恢复的异常
这是处理可恢复异常的一般方法——在这种情况下您根本不想失败,但在发生此类异常时您需要做一些事情。
<?php
try {
$methodThatThrowsException();
}
catch (DoesNotMatterException $e) {
// do some stuff and continue the execution
// note, that this exception won't be logged
}
可恢复的异常记录
和前面一样,但是你想记录这个异常。
<?php
try {
$methodThatThrowsException();
}
catch (NonCriticalExceptionThatShouldBeLogged $e) {
$this->exceptionHandler->handle($e); // log exception
// do some stuff and continue the execution
}
带有“finalizer”的不可恢复异常
您想执行一些特定的业务逻辑然后失败。您可以捕获异常,处理它,然后再次抛出它。全局异常处理程序将处理此异常并将其记录下来。
<?php
try {
$methodThatThrowsException();
}
catch (CriticalException $e) {
// do some stuff like cleanup/transaction rollback
throw $e;
}
不可恢复的异常
如果你只想记录异常并失败,你可以抛出这个异常,全局异常处理程序将捕获并记录它。
<?php
$methodThatThrowsException();
// ExceptionHandler::handle will be executed
关于php - 在 PHP 中记录自定义异常的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49038329/