Beruflich Dokumente
Kultur Dokumente
Overview
Exception logging: Don't hide exception stack traces and use appropriate logger.error method to log exceptions
Exception logging: Include adequate context information in error messages
Exception Handling : Don't handle runtime exceptions
Exception Handling : Don't ever handle java.lang.Exception or java.lang.Throwable
Exception Handling : Use global exception handler
Exception Handling : Handling Checked Exceptions
Don't ignore exceptions
Don't propagate checked exceptions. If possible recover from the checked exception gracefully. It is a burden on others.
Throwing Exceptions : Always prefer unchecked exceptions for unrecoverable errors. Don't overuse checked exceptions.
Throwing Exceptions : Favor standard exception types
Throwing Exceptions : Document exceptions thrown by your code
Use exceptions for exceptional cases.
Overview
Exception handling in java is an important part of developing robust and clean applications. When it is done wrong it ruins readability and makes
applications error prone.
Exception logging: Don't hide exception stack traces and use appropriate logger.error
method to log exceptions
Don't do this
try {
// some code throwing an checked exception
} catch (SomeCheckedException exception)
{
LOGGER.error("my error message");
}
Do this
try {
// some code throwing an checked exception
} catch (SomeCheckedException exception)
{
LOGGER.error("my error message",exception);
}
Do this
Runtime exceptions include programming errors, precondition validations and unrecoverable errors such as http communication errors. They
shouldn't be handled .
There could be cases where your code may need to recover from a runtime error. This should be rare , should be document very well
and its scope should be as limited as possible.
Don't do this
Do this:
Don't handle the runtime exceptions and let the global exception handler to handle them
void addProductToCart(String cartId,String productId) {
ResponseEntity entity = restTemplate.postForEntity(...);
// some other code
}
It makes the code unreadable and hides genuine programming errors. By handling java.lang.Exception your code handles all programming errors
such as NullPointerException etc..
There might be cases where your code may need to recover from all the exceptions: This should be very rare , should be documented very
well and its scope should as limited as possible (try block with 1 line of code). It is ideal to use global exception handler for
handling all exceptions.
It is always good practice to define an general API policy for unexpected errors. Some examples.
If an error occurs:
Best way to achieve this is introducing global exception handler for the whole application.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Throwable.class)
void RedirectView handleAllException(final Throwable exception)
{
// This component's API policy is redirecting to an error page for all the errors
// It could have been returning an ResponseEntity with 500 http status
LOG.error("handleAllException:", exception);
return redirectToErrorPage(.....);
}
}
It is a good practice to return appropriate errors and status codes for different types of exceptions. Such as returning 400 http status for llegalAr
gumentException
It is also possible and OK to handle exceptions in Controllers in more granular fashion. See here more on this.
try {
// some code
} catch (SomeException e) {
}
An empty catch block defeats the purpose of exceptions, The catch block at least should contain a comment and explain why it is appropriate to
ignore the exception. Exception should also be logged if appropriate.
Don't propagate checked exceptions. If possible recover from the checked exception gracefully. It is
a burden on others.
Don't do this
class GlobalContentReader {
static void String readContent() throws FileNotFoundException // make them suffer ! {
return readContentFromAFile(somefile);
}
}
Do this
class GlobalContentReader {
static void String readContent() {
try {
return readContentFromAFile(somefile);
} catch (FileNotFoundException ex) {
log.warning ("failed to find the content file . Using the default
content",ex);
return DEFAULT_CONTENT;
}
}
}
// a happy caller
String content = GlobalContentReader.readContent();
// continue with good path.
Don't do this :
void static String decrypt(String encrypted) throws MyDecryptionException {
try {
return decrypt(encrypted);
} catch (FileNotFoundException exception) {
// Decryption key can't be found. So throwing an checked exception . Let others
deal with it !
throw new MyDecryptionException(exception); // MyDecryptionException extends
Exception
}
}
Do this :
Java libraries provide a basic set of unchecked exceptions . Favor them to custom exception types
Do this :
void validateCart(Cart cart) {
Set<ConstraintViolation<Object>> violations = validator.validate(o);
if (!violations.isEmpty()) {
// IllegalArgumentException is standard java exception . Thrown to indicate
that an illegal or
// inappropriate argument has been passed.
throw new java.lang.IllegalArgumentException( getValidationErrors(violations)
);
}
// all was fine
}
Try to stick to the rules above and your code will be much cleaner and easier for others to use