以下是编写良好实践的方法吗?
try {
//my code here
} catch (Exception e) {
logger.error("Some error ", e);
throw new MyCustomException("Some error ", e);
}
此外,我应该.. ..
我理解使用throw
我可以在callstack的另一部分中捕获异常,但是可能额外的日志记录有一些隐藏的好处,并且也很有用。
答案 0 :(得分:13)
通常情况下,我认为您应该记录或重新抛出。同时执行这两个操作只会导致每个图层一次又一次地记录异常,这使得日志难以阅读。更糟糕的是,很难弄清楚你实际拥有多少错误 - 是7个错误,还是记录了相同错误的7层应用程序?
这意味着如果您取消异常,则会记录它并说明为什么您认为不值得重新抛出。
另一方面,如果你重新抛出异常,你知道它会被捕获并被抑制(在这种情况下捕获器会记录异常以及它被抑制的原因),或者它将从您的应用程序中冒出来并被应用程序容器捕获,该容器将捕获并记录异常。每个异常在日志中只显示一次。
答案 1 :(得分:6)
我在某些情况下使用两者,记录并抛出异常。特别是,它在API中很有用。通过抛出异常,我们允许调用者处理它,通过记录,我们可以自己确定它的根本原因。
并且,如果调用者在同一系统中,那么如果我们在每个catch中添加日志,则会有重复的日志。
答案 2 :(得分:3)
使用您建议的模式时,通常会在日志中多次报告错误事件。此外,在阅读日志时,它们之间的连接并不总是很简单。
我个人更喜欢只记录错误事件一次,并且在较高的调用级别中执行此操作。因此,我几乎从不记录和再次抛出。我通常让异常进入调用堆栈,直到它到达可以某种方式处理的上下文,这就是我记录的地方。
如果异常被包装并重新正确抛出,则应该从单个日志消息的堆栈跟踪中清楚地看到上下文。
答案 3 :(得分:2)
正确的答案是:“这取决于”
您通常希望记录您捕获的异常,因为它们对应于出错的地方。这就是为什么代码分析工具(如声纳)会在您不记录它们时发出警告的原因。
考虑以下目标:解析文件。在解析文件时,您实际上尝试解析每一行。有时某些行会出错,因此您不希望因此而停止解析文件。在这种情况下,您可能只想记录错误的行并继续保存文件。 但是,想象一下,在某些时候,您在阅读时会遇到I / O异常(例如,某些其他程序在您访问该文件时删除了该文件)。
在这种情况下,您可能希望在日志中记录遇到的错误,并抛出一个新的异常以停止处理整个文件。
简而言之,你必须考虑做什么是最好的事情。但这两种做法都不错。
答案 4 :(得分:1)
我认为您可能需要明智地使用该模式。正如您在上面所写的那样,对于每个例外,您将记录2个堆栈跟踪,这可能会在您的日志中填充过多的信息。
关于伐木与投掷,它们是两个不同的问题。抛出异常会中断执行,阻止任何进一步的工作,也许回滚数据库提交等。日志记录只会将信息转储到日志文件(或其他地方)。它更适用于调试,而且通常更难以测试。
答案 5 :(得分:0)
我知道这是个老问题,但我有另一个解决方案。
考虑一下。您可以将问题记录在 catch
块中并抛出一个新的 unchecked 异常(当然是将前一个异常传入内部)。在这样的解决方案中,日志没有溢出,异常仍然冒泡到最高级别。
try {
//my code here
} catch (SomeException e) {
logger.error("Some error occured", e);
throw new MyUncheckedException("Some error ", e);
}