php - 在 PHP 中记录自定义异常的最佳实践

标签 php logging exception-handling custom-exceptions exception-logging

我有一个自定义异常(在其他自定义异常中进一步扩展)。我的项目需要记录发生的所有 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。但是,如果我们走这条路,我的问题是:

  1. 如何将记录器注入(inject) customException?
  2. 是否会违反 SRP 原则?
  3. 它会被视为 OOP 意义上的不良做法,还是这方面的最佳做法是什么?

最佳答案

我认为将记录器注入(inject) CustomException 是不正确的,因为(如您所指)它破坏了 SRP 并增加了异常类的复杂性。

我建议您将 Exception 与 ExceptionHandler 分开。异常类应该只包含关于“什么(和哪里)出了问题”的信息。 ExceptionHandler 负责记录异常(并在需要时做一些其他处理异常的工作)。

因此您可以设置一个全局 ExceptionHandler(使用 set_exception_handlerset_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/

相关文章:

php - Laravel api类异常处理

java - Mockito 如何模拟和断言抛出的异常?

java - 从 PHP 脚本调用 Java 时出现问题

php - 在 AngularJS 应用程序中正确包含 WordPress 博客的策略

php - 如何通过用户界面设置php项目来安装数据库

java - log4j.xml 日志记录在 spring Controller 中不起作用?

java - 通过 syslog 发送 log4j2 堆栈跟踪

exception-handling - 中止的 Ajax 调用在服务器日志 : How to catch/suppress? 中给出 ClientAbortException/Broken pipe

php - PDO 不插入值

c++ - 我正在尝试用 C++ 创建一个日志记录框架,但信息没有传递给记录器的子组件,我做错了什么?