我目前正在维护一个具有大量代码库的应用程序。该应用程序仍在开发中。
我的目标是记录应用程序中抛出的所有异常。还有那些在try-catch块中被捕获的。由于代码库很大,我无法在catch块中添加单行代码或创建自定义异常类。
我试图解决它或寻找解决方案的方式是:
- 倾听整个应用程序中的类构造
- 重写Exception类(不能这样做,因为它是一个核心php类(
我最近尝试的代码是:我的测试异常(dashboardcontroller.php
(
try {
throw new Exception('custom thrown exception');
} catch (Exception $e) {
Log::info('Exception caught');
}
ExceptionsHandler.php
public function report(Exception $exception)
{
Log::info($exception);
parent::report($exception);
}
Log
[2020-03-10 17:19:09] local.INFO: Exception caught
所以问题是:在不添加需要大量更改的代码的情况下,如何记录/处理try-catch块中捕获的抛出异常?
简短的回答:你不能(据我所知(。
被捕获的异常通常被捕获是有原因的;它们在catch语句(即异常处理程序(中被处理(或者:它们应该(。要记录的是未捕获的异常。
异常永远不应该用于程序流,但它确实会发生,有时是有充分理由的:
if (fileExists('foo.txt')) {
fileDelete('foo.txt'); // May result in a race-condition
}
V.s.:
try {
fileDelete('foo.txt')
catch (IOException) {
// NO-OP
}
另一种常见模式:
while (true) {
try {
item = queue.Receive(10); // Wait max. 10 seconds
process(item); // Process item
} catch (TimeOutException) {
// Nothing on queue, handle other stuff and then continue waiting...
DoStuff();
}
}
上述模式非常常见。同样:程序流不应该使用异常,上面的队列示例肯定不应该存在,但事实是它确实存在。现实世界中的应用程序、库、API等有时只是以这种方式工作,一旦您处理第三方应用程序、图书馆或API,您就会遇到麻烦,因为您无法始终将所有内容更改为喜欢的
你能想象在上面的队列示例中,你的日志文件和一个全天候运行的应用程序的"通用应用程序范围捕获记录器"吗?
何时记录异常(也许同样重要的是:记录什么(应该根据具体情况进行考虑。