Exception 在Groovy中为异常或错误添加更多上下文
当我只想为发生的任何异常(包括解析错误甚至内存不足)添加更多上下文时,我编写如下代码Exception 在Groovy中为异常或错误添加更多上下文,exception,groovy,Exception,Groovy,当我只想为发生的任何异常(包括解析错误甚至内存不足)添加更多上下文时,我编写如下代码 try { new JsonSlurper().parseText(response) } catch (any) { throw new IllegalStateException("Cannot parse response:\n$response", any) } 这很好,但我可能最终会将OutOfMemoryError包装在IllegalStat
try {
new JsonSlurper().parseText(response)
} catch (any) {
throw new IllegalStateException("Cannot parse response:\n$response", any)
}
这很好,但我可能最终会将OutOfMemoryError
包装在IllegalStateException
中,这听起来不太正确,因为可能会有专门的异常处理机制,只用于错误
可丢弃文件
有没有办法只向异常添加更多上下文,而仍然保留其原始类型或类别?也就是说,当我得到
OOME
时,我想重新显示错误
,当我得到一些解析异常时,我想重新显示一些未检查的异常等。当然,我不想为每个类别手动执行,因为OOME
不太可能,我也不想为特殊情况生成特殊代码(尽管我仍然希望在技术上是正确的)。您可以在groovy中通过使用其功能来实现这一点。特别是,对于您的案例,它提供了您所需要的一切。使用它们,您可以动态地将contextData
对象添加/附加到异常中,您希望它随身携带:
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
然后,要在代码的其他部分检索此contextData
,只需检查异常
对象,如下所示:
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
作为groovy,以灵活的方式处理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();
}
}
希望这能有所帮助。通过使用groovy的功能,您完全可以在groovy中做到这一点。特别是,对于您的案例,它提供了您所需要的一切。使用它们,您可以动态地将contextData
对象添加/附加到异常中,您希望它随身携带:
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
然后,要在代码的其他部分检索此contextData
,只需检查异常
对象,如下所示:
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
作为groovy,以灵活的方式处理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();
}
}
希望有帮助。
我强烈建议不要做你想做的事情。有各种各样的原因。考虑下面的场景。如果<代码>响应< /代码>持有2 GB的不正确的数据?你想记录吗?如果你的应用程序使用了一些远程记录器,你想用你的网络传输2 GB的数据吗?不处理您的客户请求?如果JSON响应包含一些敏感数据怎么办?我不知道上下文,但您请求的内容听起来很可疑。解析异常通常提供一些有用的上下文,可以用来调查问题。在我的上下文中没有敏感数据。如果有东西返回2GB不正确的数据t数据,我想努力将其记录下来,以便进行调查。对我来说,这总比没有用于调查的数据好。一般来说,我同意,在泛型库中应该避免使用此类代码,但在我的代码中,这是我所期望的。我明白你的意思,我同意拥有用于调查的数据是必要的。然而,这并不只是您可以捕获任何异常,将响应转储到文件(或DB),记录错误发生并转储用于调查的数据(您可以从JSON响应生成sha1sum,并确保只转储一次响应),最后-重新显示您之前捕获的异常。当然,转储响应可能会失败,因此您需要提前考虑。这种实现是明确的,可以很好地封装。是的,您提出的建议听起来像是解决方案,但需要额外的编码和测试。在我的情况下,绝大多数响应都是真正的s购物中心(我控制他们)我希望在调查过程中直接传递它们,以减少在调查过程中的一跳。我强烈建议不要做你想做的事情。有各种各样的原因。考虑下面的场景。如果<代码>响应< /代码>持有2 GB的不正确数据?要记录吗?如果你的应用程序使用了一些远程的数据,你会怎么办?logger-您想使用您的网络传输2 GB的数据而不是处理您的客户请求吗?如果JSON响应包含一些敏感数据怎么办?我不知道上下文,但您请求的内容听起来很可疑。解析异常通常提供一些有用的上下文,可以用来调查问题。在我的文本没有敏感数据。如果有东西返回2GB不正确的数据,我想努力将其记录下来,以便进行调查。对我来说,这总比没有数据进行调查好。一般来说,我同意,在泛型库中应该避免此类代码,但在我的代码中,这是我所期望的。我明白你的意思,我同意having用于调查的数据是必不可少的。但是,使用异常并不合理。请换一种方式考虑。您可以捕获任何异常,将响应转储到文件(或DB),记录错误发生的情况,并转储用于调查的数据(您可以从JSON响应生成sha1sum,并确保只转储一次响应),最后-重新显示您之前捕获的异常。当然,转储响应可能会失败,因此您需要提前考虑。这种实现是明确的,可以很好地封装。是的,您提出的建议听起来像是解决方案,但需要额外的编码和测试。在我的情况下,绝大多数响应都是真正的small(我控制它们),所以我想直接通过它们,例外是在调查过程中少跳一次。