当我只想向已发生的任何异常添加更多上下文(包括解析错误,甚至内存不足)时,我将编写以下代码
try {
new JsonSlurper().parseText(response)
} catch (any) {
throw new IllegalStateException("Cannot parse response:\n$response", any)
}
这很好用,但是我可能最终将OutOfMemoryError
包裹在IllegalStateException
中,听起来似乎不正确,因为进一步可能有专门针对Error
抛出对象的异常处理机制
有什么方法可以向异常添加更多上下文并仍然保留其原始类型或类别?即当我得到OOME
时,我想重新抛出Error
,当我得到一些解析异常时,我想重新抛出一些未经检查的异常,等等。当然,我不想为每个类别手动进行,因为OOME
不太可能出现,并且我不想为特殊情况生成特殊代码(尽管在技术上我还是想保持正确)。
答案 0 :(得分:0)
您绝对可以通过使用其metaprogramming功能来做到这一点。特别是,metaclasses为您提供所需的一切。使用它们,您可以将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();
}
}
希望这会有所帮助。