简体   繁体   中英

Throw exception vs Logging

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.

Normally, I'd argue that you should either log or rethrow. 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.

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.

And, if the caller is in the same system, then if we add logs in every catch, there will be duplicate logs.

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.

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).

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.

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.

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.

I know that is really old question, but I have an another solution.

Consider this. You can log the problem in catch block and throw a new unchecked exception (of course with passing the previous one inside). In such solution there is no overflow in the logs and exception still bubble up to the highest level.

 try { //my code here } catch (SomeException e) { logger.error("Some error occured", e); throw new MyUncheckedException("Some error ", e); }

My opinion.

When you need to throw an exception, no matter if it is a Checked or UnChecked(Most RD would not catch this.). It means that you want to do something else by stopping the process.

When you need to log something. It means you want to track it.

It's quite different things. You need to check what you really need.

BTW: If your exception was thrown by getting no data from DB. I suggest you to modify the process to return an empty Data Object(POJO). It is better than throwing an exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM