exception - 在 Groovy 中为异常或错误添加更多上下文
问题描述
当我只想为发生的任何异常(包括解析错误甚至内存不足)添加更多上下文时,我编写代码如下
try {
new JsonSlurper().parseText(response)
} catch (any) {
throw new IllegalStateException("Cannot parse response:\n$response", any)
}
这很好用,但我最终可能会OutOfMemoryError
被包裹在IllegalStateException
其中听起来不正确,因为进一步可能会有专门的异常处理机制仅用于Error
throwables。
有什么方法可以为异常添加更多上下文并仍然保留其原始类型或类别?即当我得到时OOME
,我想重新抛出Error
,当我得到一些解析异常时,我想重新抛出一些未经检查的异常等。当然我不想为每个类别手动执行它,因为OOME
这不太可能而且我不会不想为极端情况生成特殊代码(虽然我仍然希望在技术上是正确的)。
解决方案
你绝对可以通过使用它的元编程特性在 groovy 中做到这一点。特别是,对于您的案例,元类提供了您需要的一切。使用它们,您可以动态地将contextData
对象添加/附加到exception
您希望它携带的对象:
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
然后要contextData
在代码的其他部分检索它,只需exception
像这样检查对象:
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
在那里,我使用这个论点contextDataHandler
作为一种灵活的方式Closure
来处理contextData
。
以下是一个完整的工作演示:
import java.time.LocalDateTime
class ExceptionEnhancer {
static void main(String[] args) {
def logger = { println "${LocalDateTime.now()} - Context Data = [$it]" }
doSomethingWithContextData logger
}
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
public static void throwsBasicException() throws IOException {
throw new IOException();
}
}
希望这可以帮助。
推荐阅读
- android - 在 android studio 上使用 Oboe 时出现未知警告选项“-Wshadow-field”错误
- java - 对象列表上的 JUnit Mockito ReflectionEquals
- c# - Automapper ProjectTo 在与自定义映射一起使用时不起作用
- c++ - Destructor of shared_ptr Object never called
- excel - 如果行中的一个单元格包含“颜色 AP”,VBA 中有没有办法将一行复制到另一个工作表?
- javascript - evaluateJavaScript 在 WkWebview 上绘制数据缓慢(非常慢)
- python - 来自数据库的数据的前端部署
- python - python, if line.startswith("word") 检查第 20 行并打印
- javascript - 嵌套的 JavaScript 'for' 循环 - 为什么第一个循环不运行整个长度?
- javascript - 在视口中运行 CSS 关键帧动画