Java 抛出异常与日志记录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22072343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Throw exception vs Logging
提问by xrabbit
Is the following way to code good practice?
以下是编写良好实践的方法吗?
try {
//my code here
} catch (Exception e) {
logger.error("Some error ", e);
throw new MyCustomException("Some error ", e);
}
Moreover, should I..
而且,我该不该..
- use only the logger?
- throw only the exception?
- do both?
- 只使用记录器?
- 只抛出异常?
- 两者都做?
I understand that with throw
I can catch the exception in another part of the callstack, but maybe additional logging has some hidden benefits and is useful as well.
我知道throw
我可以在调用堆栈的另一部分捕获异常,但也许额外的日志记录有一些隐藏的好处并且也很有用。
采纳答案by Abimaran Kugathasan
I use both in some cases, logging and throwing the exception. Specially, it's useful in APIs. By throwing the exception, we allow the caller to handle it, and by logging, we can identify the root cause of it ourself.
我在某些情况下同时使用,记录和抛出异常。特别是,它在 API 中很有用。通过抛出异常,我们允许调用者处理它,通过记录,我们可以自己确定它的根本原因。
And, if the caller is in the same system, then if we add logs in every catch, there will be duplicate logs.
而且,如果调用者在同一个系统中,那么如果我们在每个catch中添加日志,就会有重复的日志。
回答by Brian Agnew
I think you may need to use the pattern judiciously. As you've written the above, for each exception you're going to log 2 stacktraces and that may fill your logs with excessive information.
我认为您可能需要明智地使用该模式。正如您在上面写的那样,对于每个异常,您将记录 2 个堆栈跟踪,这可能会用过多的信息填充您的日志。
With respect to logging vs. throwing, they're two separate concerns. Throwing an exception will interrupt your execution, prevent any further work, perhaps rollback database commits etc. Logging will simply dump info to the log file (or elsewhere). It's of more use for debugging, and often much more difficult to test.
关于记录与投掷,它们是两个独立的问题。抛出异常将中断您的执行,阻止任何进一步的工作,可能回滚数据库提交等。日志记录只会将信息转储到日志文件(或其他地方)。它更适用于调试,而且通常更难测试。
回答by Eyal Schneider
When using the pattern you suggest, you usually end up with error events being reported multiple times in the log. In addition, it's not always simple to connect between them when reading the log.
使用您建议的模式时,您通常会在日志中多次报告错误事件。此外,在阅读日志时,它们之间的连接并不总是那么简单。
Personally I prefer logging error events only once, and doing it in the higher call levels. Therefore I almost never log & re-throw. I usually let the exception go up the call stack until it reached a context where it can be handled somehow, and this is where I log.
我个人更喜欢只记录一次错误事件,并在更高的调用级别中进行。因此,我几乎从不登录并重新抛出。我通常让异常进入调用堆栈,直到它到达可以以某种方式处理的上下文,这就是我记录的地方。
If the exceptions are wrapped and re-thrown correctly, the context should be perfectly clear from the stack traces of the single log message.
如果异常被正确包装和重新抛出,则上下文应该从单个日志消息的堆栈跟踪中完全清楚。
回答by Arnaud Potier
The proper answer would be: "it depends"
正确的答案是:“视情况而定”
You do want in general log the exceptions that you catch, since they correspond to something going wrong. That is why code analysis tools such as sonar will raise warnings when you do not log them.
通常,您确实希望记录您捕获的异常,因为它们对应于出现问题。这就是为什么代码分析工具(例如声纳)在您不记录它们时会发出警告的原因。
Consider the following taks: parsing a file. While parsing the file you actually try to parse each line. Sometimes some lines will be malformed, and therefore you don't want to stop parsing the file because of it. In that case, you probably want to just log the wrong line and keep going on the file. However, imagine that at some point you encounter an I/O exception while reading (for example some other program deleted the file while yours was accessing it).
考虑以下任务:解析文件。在解析文件时,您实际上尝试解析每一行。有时某些行会格式错误,因此您不想因此而停止解析文件。在这种情况下,您可能只想记录错误的行并继续处理文件。但是,想象一下,在某些时候您在读取时遇到了 I/O 异常(例如,某些其他程序在您访问文件时删除了该文件)。
In this case, you will probably want to log your log the error you encounter, and throw a new exception to stop processing the whole file.
在这种情况下,您可能希望将遇到的错误记录在日志中,并抛出一个新异常以停止处理整个文件。
So in short, you have to think about what is the best thing to do. But both practices are not bad.
所以简而言之,你必须考虑什么是最好的。但是这两种做法都不错。
回答by gustafc
Normally, I'd argue that you should either log orrethrow. Doing both will just cause every layer to log the exception again and again, which makes the logs hard to read. Even worse, it's hard to figure out how many errors you actually have - was it seven errors, or seven layers of the app which logged the same error?
通常,我认为您应该记录或重新抛出。两者都做只会导致每一层一次又一次地记录异常,这使得日志难以阅读。更糟糕的是,很难弄清楚您实际上有多少错误 - 是七个错误,还是记录相同错误的应用程序的七层?
This means that if you suppress an exception, you log it and say why you didn't think it was worth rethrowing.
这意味着如果你抑制了一个异常,你会记录它并说明为什么你认为它不值得重新抛出。
On the other hand, if you re-throw the exception, you know it's either going to be caught and suppressed (in which case the catcher logs the exception and why it was suppressed), or it will bubble up out of your app and be caught by the app container, which will catch and log the exception. Every exception shows up once and only once in the logs.
另一方面,如果你重新抛出异常,你知道它要么被捕获并抑制(在这种情况下,捕获器记录异常以及它被抑制的原因),或者它会从你的应用程序中冒出来并被由应用程序容器捕获,它将捕获并记录异常。每个异常在日志中仅出现一次。