对抛出的任何异常做出反应
React to any exception being thrown
问题
我想对抛出的异常事件做出反应。所以如果有人写
throw new FooException();
系统应该通知我,以便我能够对该事件做出反应。
我也会接受建议解决此问题的框架或工具的答案,包括字节码操作。
详情
- 它必须与任何异常一起工作;
Exception
的子类,包括 RuntimeException
。我对 Error
s 不感兴趣。
- 它还必须触发 已经捕获的 异常,无论它发生在代码库的哪个位置(包括 JDK 内部)。
所以如果有人这样做
try {
foo();
} catch (FooException e) {
...
}
我也希望能够对此做出反应,而无需修改 ...
的源代码。
因此,围绕主流程的 try-catch-em-all 不起作用,它不会捕获已经捕获的异常。
Thread.setDefaultUncaughtExceptionhandler(...)
也一样,不能解决问题。
请不要建议调整我的设计或者这可能是一个 XY 问题,我知道并且主要是在问,因为我很好奇如何实现这一点。
不完全确定这是否可行,但也许可以将处理程序创建为静态方法,这样您就可以执行类似的操作
ErrorHandler.handle(Class<ExceptionClass> clazz)
并将该代码注入 class 路径上可用的每个异常 class 构造函数?您可以通过使用反射库扫描 class 路径来获取异常,然后尝试使用 javassist 或类似的东西对那些 classes 进行字节码操作?
这些东西应该在某些代理库中完成,您需要 运行 您的应用程序使用此 agentlib,以便在实际应用程序启动之前完成操作。
面向方面编程可以提供解决方案:基本上,它允许您在特定位置(称为“连接点”)“添加”代码片段(称为“建议”)
例如,对于 AspectJ,用于定义记录方法调用抛出的每个异常的建议的代码可能如下所示(我还没有尝试过):
@Aspect
class ExceptionMonitoring {
@AfterThrowing(pointcut = "call(* *.*(..))", throwing = "java.lang.Exception")
public void logException(JoinPoint joinpoint, Exception exception) {
System.out.println("The method " + joinpoint.getSignature().getName() + " threw " + exception);
}
}
问题
我想对抛出的异常事件做出反应。所以如果有人写
throw new FooException();
系统应该通知我,以便我能够对该事件做出反应。
我也会接受建议解决此问题的框架或工具的答案,包括字节码操作。
详情
- 它必须与任何异常一起工作;
Exception
的子类,包括RuntimeException
。我对Error
s 不感兴趣。 - 它还必须触发 已经捕获的 异常,无论它发生在代码库的哪个位置(包括 JDK 内部)。
所以如果有人这样做
try {
foo();
} catch (FooException e) {
...
}
我也希望能够对此做出反应,而无需修改 ...
的源代码。
因此,围绕主流程的 try-catch-em-all 不起作用,它不会捕获已经捕获的异常。
Thread.setDefaultUncaughtExceptionhandler(...)
也一样,不能解决问题。
请不要建议调整我的设计或者这可能是一个 XY 问题,我知道并且主要是在问,因为我很好奇如何实现这一点。
不完全确定这是否可行,但也许可以将处理程序创建为静态方法,这样您就可以执行类似的操作
ErrorHandler.handle(Class<ExceptionClass> clazz)
并将该代码注入 class 路径上可用的每个异常 class 构造函数?您可以通过使用反射库扫描 class 路径来获取异常,然后尝试使用 javassist 或类似的东西对那些 classes 进行字节码操作?
这些东西应该在某些代理库中完成,您需要 运行 您的应用程序使用此 agentlib,以便在实际应用程序启动之前完成操作。
面向方面编程可以提供解决方案:基本上,它允许您在特定位置(称为“连接点”)“添加”代码片段(称为“建议”)
例如,对于 AspectJ,用于定义记录方法调用抛出的每个异常的建议的代码可能如下所示(我还没有尝试过):
@Aspect
class ExceptionMonitoring {
@AfterThrowing(pointcut = "call(* *.*(..))", throwing = "java.lang.Exception")
public void logException(JoinPoint joinpoint, Exception exception) {
System.out.println("The method " + joinpoint.getSignature().getName() + " threw " + exception);
}
}