0

I have some basic knowledge of Exception Handling, but I still don't understand when custom exceptions are really needed to be created.

Well, I knew that if custom exceptions provide some extra fields, then custom exceptions are really helpful, and otherwise we can use standard exceptions.

But my question is:

  1. If we go for standard exceptions, let's say, if I use throw new RuntimeException("blah blah") in more than one microservice, then how would I be able to quickly identify which microservice threw this exception?. Of course, I would be able to identify it by looking at the logs, BUT, ss it a good practice to throw standard exceptions rather than using custom exceptions?
  2. In my project, in each microservice, I have seen custom exceptions are being created, they just extend RuntimeException and no extra information in any of these custom exceptions. Would you consider this good or bad practice?
  3. If I search google on this topic, a common snippet of code used is this:

NameNotFoundException:

public class NameNotFoundException extends Exception {    
    public NameNotFoundException(String message) {
        super(message);
    }    
}

Do you think that basic custom exceptions like this should be used at all?

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
john
  • 925
  • 1
  • 12
  • 20
  • 1
    [When should we create our own Java exception classes?](https://stackoverflow.com/questions/22698584/when-should-we-create-our-own-java-exception-classes) – MT756 Mar 04 '20 at 19:13

5 Answers5

1

We deal with REST calls, a lot (so much that we wrote our own wrapper around JDK's HTTP Client); various times calling not only our endpoints. When talking to those endpoints we define a custom Exception, like:

class OurCustom extends ... {

       int httpCode;
       String receivedMessage;
       OffSetDateTime receivedAt;

}

My point is, this can solve two problems.

  • Intent

When I see that a certain service throws this OurCustom, I immediately know what is it's intent, I understand what actions I should take and what methods it has. If that would have been a plain RuntimeException, it would have been a bit more difficult.

  • Additional debug info

You can add more stuff to a custom Exception, not just the message itself, like httpCode or message. This simplifies life for the people that have to interact with this Exception. But simply extending it without any additional info might be of a value too, it depends.

So yes, there are cases where I find this very useful.

Eugene
  • 117,005
  • 15
  • 201
  • 306
1

The RuntimeException is also thrown by the JVM itself in error situations. So you can't distinguish easily if you want to do handling on your exceptions in the catch-blocks.

If we go for Standard Exception, lets say, if I use throw new RuntTimeException("blah blah") in more than one microservices, then how do we easily identify quickly, from which microservice this exception showing? (lets say we have 30 microservices). Ofcourse, by looking at log, we can able to identify, from which exception getting.. BUT, Is this a good practise to throw Standard exceptions rather than Custom Exceptions?

I guess microservices have some kind of web API (i.e. HTTP), so the caller must not see "naked" RuntimeExceptions - otherwise your API is depending on your programming language and you are stuck to Java. If you mean you're doing your exception mapping based on RuntimeExceptions, you're maybe not precise enough - what if some library you use throws a RuntimeException? Better use your own Exception class.

The minimal mapping would be mapping exceptions to HTTP error codes IMHO, i.e. 200/OK, 400/Bad Request or 403/Forbidden.

2) In my project, In each microservice, I have seen Custom Exceptions created, they just extends RuntimeException and no extra information in any of these custom exceptions. Do you say, we are doing wrong?

There's nothing wrong with that. Error codes or messages are there for handling and/or displaying them. You can take a look on some exception mapping techniques of Jersey JAX-RS service here.

Do, you think above Custom Exceptions should not be created at all?

I think you need a defined simple way in each of your microservices to produce error messages. A very simple way is mapping exceptions to HTTP status codes (above example). Another way is to explicitly send the HTTP status without using exceptions. Passing around status code is something that is ok for very simple code:

return Response
  .status(Response.Status.OK)
  .build();

My recommendation: Start with the most simple approach (direct status codes) and change to working with more abstraction like exception mappers if needed (KISS - Keep It Sound and Simple).

s.fuhrm
  • 438
  • 4
  • 9
1

I'm using always custom exceptions in my projects:

public class BaseAppException extends RuntimeException {

    public BaseAppException(String message) {
        super(message);
    }

    @Override
    public synchronized Throwable fillInStackTrace() {
        // disable Stacktrace per default
        return this;
    }

    public ResponseEntity<ErrorResponse> toResponseEntity(){
        return [...]
    }
}

public UserNotFoundException extends BaseAppAxception {

    public UserNotFoundException(String idUsed){
        super("No User found for ID:" + idUsed);
    }
    [...]
}

So I can handle all my exception in the same way (pseudo code):

@ExceptionHandler(BaseAppException.class)
public final ResponseEntity<ErrorResponse> handleAppException(BaseAppException ex) {
    return ex.toResponseEntity();
}

@ExceptionHandler(Exception.class)
public final ResponseEntity<ErrorResponse> handleAppException(Exception ex) {
    ErrorResponse error = new ErrorResponse(ApplicationConstants.SERVER_ERROR, ex.getMessage());
    return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}

This is just one example, but I hope I could show the idea. You should also use custom exceptions to hide the error messages. See my UserNotFoundException

alex
  • 8,904
  • 6
  • 49
  • 75
1

Generally, custom exceptions are needed in the following situations:

  1. To flag an error/exception situation which does not fit into the standard exceptions.
  2. To distinguish it from the standard exceptions.
  3. To add additional information which will be useful for logging/debugging etc.

In my project, In each microservice, I have seen Custom Exceptions created, they just extends RuntimeException and no extra information in any of these custom exceptions. Do you say, we are doing wrong?

There is nothing wrong about it but if it does not match with any of the cases mentioned above, it is unnecessary.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

You can do more with Exceptions than just outputting a message. Even if your custom exceptions are nothing more than a wrapper of the base class, it gives you options on how best to handle the various exceptions. Sometimes you just need to update a UI component. Sometimes you need to log the error for further examination. Maybe you need to force close the application or a window. For example, if you have a method that validates some data, you might have an exception for invalid data that just changes UI elements to error styling. What if the validator itself throws an exception? Then you'll want to log it and notify the user that something is seriously wrong.

Ryan
  • 1,762
  • 6
  • 11