Throw exception vs Logging
Asked Answered
C

9

45

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.

Carper answered 27/2, 2014 at 15:3 Comment(2)
Seems fine to me, as long as MyCustomException is a checked Exception.Vanzandt
thanks every one for your replies! you helped me very much to understand how to write logging/exception handling.Carper
G
19

I use both in some cases, logging and throwing the exception. Especially, 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 ourselves.

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

Geometrid answered 27/2, 2014 at 15:9 Comment(1)
I agree with @Kugathasan Abimaran. I am currently working on an API and need to look at my log file quiet often when something goes wrong. At the same time I have to throw an exception to notify the clientJaejaeger
N
31

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.

Na answered 27/2, 2014 at 15:33 Comment(1)
that should be the correct answer. it also solves the obvious DRY (dont repeat yourself) problem with "some error"Stay
G
19

I use both in some cases, logging and throwing the exception. Especially, 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 ourselves.

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

Geometrid answered 27/2, 2014 at 15:9 Comment(1)
I agree with @Kugathasan Abimaran. I am currently working on an API and need to look at my log file quiet often when something goes wrong. At the same time I have to throw an exception to notify the clientJaejaeger
T
9

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.

Tiernan answered 27/2, 2014 at 15:12 Comment(0)
T
3

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.

Trisyllable answered 27/2, 2014 at 15:13 Comment(1)
+1 for pointing out that some things go wrong, other things go very wrong, and the difference is the key.Dualpurpose
C
1

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.

Colleencollege answered 27/2, 2014 at 15:11 Comment(0)
A
1

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.

Alessandro answered 4/7, 2022 at 9:39 Comment(0)
L
0

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);
}
Linsang answered 9/3, 2021 at 10:5 Comment(0)
M
0

You can log the error and return the status code to notify the client why the error happened. For example:

if(inValidInputFromClient) {
    log.error("in valid input from client");
    return new ResponseEntity<ReturnType>(HttpStatus.BAD_REQUEST);
}

try {
    //my code here
} catch (Exception e) {
    log.error("Some error occurred", e);
    return new ResponseEntity<ReturnType>(HttpStatus.INTERNAL_SERVER_ERROR);
}

This way, the client will handle the error accordingly.

Matthieu answered 18/10, 2023 at 8:45 Comment(0)
F
0

We normally log the exception so that its there when you want to debug the application. And then throw our own custom exception with the actual exception message so that it can be displayed to the clients if need be.

try {
    //my code here
} catch (Exception e) {
    logger.error("Some error ", e);
    throw new MyCustomException("Unable to process XYZ: ", e.getMessage());
}

This way you will not loose the actual exception trace in your log files and at the same time have your custom exception contain only the absolute required message.

Fourposter answered 23/7 at 6:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.