Is it bad practice to throw multiple custom exceptions in Java?

No. It is good practice.

The only situation where multiple exceptions might be a (slightly) bad idea is if there is absolutely no possibility (ever!) of catching individual exceptions; i.e. the fine-grained exceptions won't serve any functional purpose. However, my opinion is that if you can make that assertion, then there is probably something wrong with the way that you / your team is using Java. And the counter-argument is that sensible use of multiple custom exceptions will help you to document the APIs ... even if you are never going to do more than catch-log-and-bail-out at runtime.

This is not to say that lots of custom exceptions will always be good:

  • If you go overboard and create a separate exception for everything, then you are probably adding unnecessary complexity. (In a lot of cases, different exception messages are sufficient.)

  • If you don't have a sensible inheritance hierarchy for your custom exceptions, then you may end up regretting it. (A well-designed hierarchy allows you to catch "classes" of exceptions, or declare methods as throwing them. It can make your code simpler.)

Answer from Stephen C on Stack Exchange
Top answer
1 of 5
7

Is it bad practice to throw multiple custom exceptions in Java?

No. It is good practice.

The only situation where multiple exceptions might be a (slightly) bad idea is if there is absolutely no possibility (ever!) of catching individual exceptions; i.e. the fine-grained exceptions won't serve any functional purpose. However, my opinion is that if you can make that assertion, then there is probably something wrong with the way that you / your team is using Java. And the counter-argument is that sensible use of multiple custom exceptions will help you to document the APIs ... even if you are never going to do more than catch-log-and-bail-out at runtime.

This is not to say that lots of custom exceptions will always be good:

  • If you go overboard and create a separate exception for everything, then you are probably adding unnecessary complexity. (In a lot of cases, different exception messages are sufficient.)

  • If you don't have a sensible inheritance hierarchy for your custom exceptions, then you may end up regretting it. (A well-designed hierarchy allows you to catch "classes" of exceptions, or declare methods as throwing them. It can make your code simpler.)

2 of 5
7

Is it bad practice to throw multiple custom exceptions in Java?

Generally speaking: No. Why should it?

As with everything: Abstraction is your friend.

Is it necessarry to have a CustomerNotFound Exception and a ProductNotFound Exception? Or are your requirements just a more abstract NotFoundException? The context could help to determine, what was missing. Having different exceptions for the sake of having them is nonsense.

Is it necessary, each layer of your application having custom exceptions? Exceptions are a way to report, that an intended action failed due to some reason.

  • Say, you have a controller which asks the service-layer to retrieve data, which in turn asks the DA-layer to read values from the DB. The resultset is empty. The service gets the empty resultset and throws a NotFoundException the service communicates, the failure of the action due to a missing result.

  • Say, the controller needs the service to do the payrolls for employees. And the service is asked to do the payroll for the employee with ID 123456, and in turn asks a service to retrieve the employee - but no emloyee could be found.

There are two ways to deal with that:

1) You throw a NotFound exception in the DA-Layer, catch it in the payroll-service and rethrow a PayrollServiceException wrapping the NotFoundException with the message Exmployee could not be found

2) You throw a NotFound exception in the DA-Layer and do not catch it in the payroll service and catch it instead a layer above.

I would go for (2), since in (1) the information, that the action failed because of a missing employee is redundant.

๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ java โ€บ user-defined-custom-exception-in-java
User-Defined Custom Exception in Java - GeeksforGeeks
Provide constructors to initialize the exception with custom messages. Add methods to provide additional details about the exception. (this is optional) Example 1: Checked Custom Exception (Real-World Scenario)
Published ย  August 14, 2025
๐ŸŒ
Baeldung
baeldung.com โ€บ home โ€บ java โ€บ core java โ€บ create a custom exception in java
Create a Custom Exception in Java | Baeldung
May 11, 2024 - In this case, weโ€™ll need a custom unchecked exception similar to the previous one, as this error will only be detected during runtime. To create a custom unchecked exception, we need to extend the java.lang.RuntimeException class:
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 33412319 โ€บ how-to-managing-multiple-custom-exceptions-in-java
android - How to Managing multiple custom exceptions in Java - Stack Overflow
I prefer to make them private final; that also helps spotting when they are not correctly initialized. For your actual problem: you could start with having a abstract "base" exception that provides a constructor/getter. Repeating yourself three times .... is basically a very bad idea. ... the approach to use the multi catch works because ex will be of the most common type that all the exceptions do have.
Top answer
1 of 9
274

You should be able to create a custom exception class that extends the Exception class, for example:

class WordContainsException extends Exception
{
      // Parameterless Constructor
      public WordContainsException() {}

      // Constructor that accepts a message
      public WordContainsException(String message)
      {
         super(message);
      }
 }

Usage:

try
{
     if(word.contains(" "))
     {
          throw new WordContainsException();
     }
}
catch(WordContainsException ex)
{
      // Process message however you would like
}
2 of 9
131

You need to create a class that extends from Exception. It should look like this:

public class MyOwnException extends Exception {
    public MyOwnException () {

    }

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

    public MyOwnException (Throwable cause) {
        super (cause);
    }

    public MyOwnException (String message, Throwable cause) {
        super (message, cause);
    }
}

Your question does not specify if this new exception should be checked or unchecked.

As you can see here, the two types are different:

  • Checked exceptions are meant to flag a problematic situation that should be handled by the developer who calls your method. It should be possible to recover from such an exception. A good example of this is a FileNotFoundException. Those exceptions are subclasses of Exception.

  • Unchecked exceptions are meant to represent a bug in your code, an unexpected situation that you might not be able to recover from. A NullPointerException is a classical example. Those exceptions are subclasses of RuntimeException

Checked exception must be handled by the calling method, either by catching it and acting accordingly, or by throwing it to the calling method. Unchecked exceptions are not meant to be caught, even though it is possible to do so.

๐ŸŒ
Stackify
stackify.com โ€บ java-custom-exceptions
Implement Custom Exceptions in Java: Why, When and How
May 1, 2023 - Learn 4 best practices for custom exceptions in Java. Understand when and how to use them in your application.
Top answer
1 of 1
4

Generally custom exceptions should be defined in the top level. Because, almost universally, these exceptions are part of the interface of the package or module.

If the user cannot see them, then how are they going to catch them separately? And if you don't want to catch them separately, then why would you need separate classes?

However, if you must, you can include them into a class for which they are required:

public class SeatReservationSystem {
    public static class ReservationFailedException {
        ... constructors taking a message ...
    }

    public static class SeatTakenException extends ReservationFailedException {
        ... constructors taking a message ...
    }

    public static class OutsideAgeException extends ReservationFailedException  {
        ... constructors taking a message ...
    }

    ....
}

After that you can create any method that returns them as required. Don't create methods that throw them as the compiler won't see those as exit points of the block you're in, and you'll get strange situations.

Here is some code to show what I mean:

// wrong
public static void throwRuntimeException() throws RuntimeException {
    throw new RuntimeException();
}

// correct, but dangerous
public static RuntimeException createRuntimeException() {
    return new RuntimeException();
}

public static void main(String[] args) {
    String initializeMeOrThrowException;
    if (new Random().nextBoolean()) {
        // compiler doesn't recognize that the method always throws an exception 
        throwRuntimeException();

        // this the compiler can understand, there is an explicit throw here:
        // throw createRuntimeException();

        // but this is the pitfall, it doesn't do anything:
        // createRuntimeException();
    } else {
        initializeMeOrThrowException = "Initialized!";
    }

    // Compiler error for throwRuntimeException and createRuntimeException without throws:
    // "The local variable initializeMeOrThrowException may not have been initialized"
    System.out.println(initializeMeOrThrowException); 
}

However, experience learns me that I forget the throws statement for the throw createException(...); method, and the stupid compiler doesn't warn me about that (even though the statement is utterly useless without it). So I try and not use either.


Note that I'm not certain if you should use exceptions for this. If your system is a reservation system, then refusing tickets is not that exceptional. Returning a ReservationResult makes more sense.

Top answer
1 of 1
1

I will try to give a few examples in Java as I am unsure from the picture and your statement:

where you would declare multiple custom exceptions like so in a single class:

What you precisely mean with the declare multiple custom exceptions in a single class.

Interface

In Java you can either define a Interface and implement that and use it in typing like so:

interface CustomException {
   String getMessage();
}

Then create a class that implements it.

class ApplicationException implements CustomException {
  public String getMessage() {
    return "Uh oh..";
  }
}

And when you throw anything you can get away with catching only CustomException.

try {
   // do something
}
catch( CustomException ce) {
  // do something with the CustomException
}

Base class

The other way you can go is to extend one of the built in Exception classes like RuntimeException or just Exception itself.

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

Then you can extend from that custom class and use it in typing as normal.

class ApplicationException extends CustomException {
  public ApplicationException(String message) {
    super(message);
  }
}

Then this works again like previously:

try {
   // do something
}
catch( CustomException ce) {
  // do something with the CustomException
}

Inside the catch you catch them all in one go. If you need to do different logic on different catches you can do separate catch blocks otherwise the other option you can do is:

try {
 // do something
}
catch ( ApplicationException | IllegalArgumentException e) {
  // do something with an error that is either a ApplicationException or a IllegalArgumentException
}

Non conventional

This I am putting here for completeness sake but it is not conventional. You could create one file in your project called Exception.java. Inside you can define as many classes as you want and you can refer to them by importing them but it is not the idiomatic way to write Java.

So inside Exception.java :

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

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

Hope this helps you out and continues you on your journey.

Find elsewhere
๐ŸŒ
Javatpoint
javatpoint.com โ€บ custom-exception
Java Custom Exception - javatpoint
Java Custom Exception. If you are creating your own Exception that is known as custom exception or user-defined exception.Let's see example of custom exception.
๐ŸŒ
Alvin Alexander
alvinalexander.com โ€บ java โ€บ java-custom-exception-create-throw-exception
Java: How to create and throw a custom exception | alvinalexander.com
As you can see, all you need to do to throw your custom exception is (1) create a new instance of the exception (new AlsCustomException("Anything but zero ...")), and then (2) throw that exception with the throw keyword. With those two pieces in place, we'll create a "driver" class with a main ...
๐ŸŒ
DZone
dzone.com โ€บ data engineering โ€บ databases โ€บ implementing custom exceptions in java
Implementing Custom Exceptions in Java
November 13, 2017 - Learn why and how to create and code custom exceptions in Java, how to properly document them and link to those docs, and general best practices for their use.
๐ŸŒ
LabEx
labex.io โ€บ tutorials โ€บ java-creating-custom-java-exceptions-117405
Java Exception Handling | Custom Exceptions | LabEx
In addition, we define a throwable exception that defines the underlying exception or the cause of our exception. In our case, the underlying exception is ArrayIndexOutOfBounds. We can update the get() method in the MyArray class to throw the custom unchecked exception.
๐ŸŒ
How to do in Java
howtodoinjava.com โ€บ home โ€บ exception handling โ€บ effective approach for creating custom exceptions in java
Effective Approach for Creating Custom Exceptions in Java
April 7, 2023 - We have been using handling java custom exceptions in our code for almost every industry standard application. Usual approach is to create some custom exception classes extending the base Exception class. These classes are generally mapped to ...
๐ŸŒ
Tutorialspoint
tutorialspoint.com โ€บ java โ€บ java_custom_exception.htm
Java - Custom Exception
The following InsufficientFundsException class is a user-defined exception that extends the RuntimeException class, making it a unchecked exception. An RuntimeException class is like any other class, containing useful fields and methods. class InsufficientFundsException extends RuntimeException { private double amount; public InsufficientFundsException(double amount) { this.amount = amount; } public double getAmount() { return amount; } }
๐ŸŒ
Vultr Docs
docs.vultr.com โ€บ java โ€บ examples โ€บ create-custom-exception
Java Program to Create custom exception | Vultr Docs
December 16, 2024 - In this article, you will learn how to create and use custom exceptions in Java.
๐ŸŒ
CodingNomads
codingnomads.com โ€บ what-are-custom-exceptions-java
Custom Exceptions in Java
While Java has built-in exceptions, it is also possible to create your own custom subclasses that extend the Exception class.
Top answer
1 of 3
4

In the spirit of the question as asked:

You would have to catch the various exceptions within your method, and then throw a CustomException from your catch block. The ability for an exception to "wrap" around another exception is built in via the Exception class itself (see the Exception(Throwable cause) constructor).

public void method() throws IOException, CustomException {
    try {
        //Body of the method
    } catch (IllegalArgumentException | InstantiationException | IllegalAccessException e) {
        throw new CustomException(e);
    }
}

That said, IllegalArgumentException is not a checked exception, so you wouldn't have to declare it anyway.

Also worth pointing out, the above is based on you specifying that you want to create a custom exception. Another option is to declare in your throws clause some type that is a common base class of the various checked exceptions that might actually be thrown. For example, both of the checked exceptions in your list are subclasses of ReflectiveOperationException, so you could just say

public void method() throws IOException, ReflectiveOperationException {
    //Body of the method
}

The trade-off, of course, is that you're not being as informative to those writing code that calls your method, so that may limit the quality of their exception handlers. In the extreme, you could just say throws Thorwable, but this is pretty poor form.

2 of 3
1

Declare a CustomException class that declares only constructors with these specific classes.
In this way it can only wrapped these exceptions and not any other.

public class CustomException extends RuntimeException{

    public CustomException(IllegalArgumentException e) {
        super(e);
    }

    public CustomException(IllegalAccessException  e) {
        super(e);
    }

    public CustomException(InstantiationException e) {
        super(e);
    }

}
๐ŸŒ
Medium
medium.com โ€บ @gaddamnaveen192 โ€บ java-custom-exceptions-how-they-work-under-the-hood-e268ba1bfadd
Java Custom Exceptions: How They Work Under the Hood | by Gaddam.Naveen | Medium
March 13, 2025 - // Step 1: Create the custom exception class class InsufficientFundsException extends Exception { // Constructor to pass a custom error messageโ€ฆ ... "Java Developer | scalable solutions | Sharing insights on Spring Boot, microservices, and clean code."
Top answer
1 of 3
2

Yes. There are two ways to do this:

Class hierarchies

This one only applies if you are the one designing the exceptions. If that doesn't describe this case, move on to the next chapter.

If you have, say, a user authentication API, you would presumably want to create a whole bevy of exceptions such as UserNotFoundException, IncorrectPasswordException, UserFrozenException, IpBlockedException, and more.

If you make sure all those exceptions extend a single exception type (AuthenticationException), like so:

public class AuthenticationException extends Exception {
    public AuthenticationException(String msg, Throwable cause) {
        super(msg, cause);
    }

    public AuthenticationException(String msg) {
        super(msg);
    }
}

public class UserNotFoundException extends AuthenticationException {
    public UserNotFoundException(String username) {
        super(username);
    }
}

// and so on

then a caller can choose, which is why this makes for such a great API design.

IF a caller needs to have custom reactions depending on what kind of authentication problem occurs, they can catch, say, UserNotFoundException. But if they don't particularly care, they can catch AuthenticationException.

Note that java itself does this, too. GeneralSecurityException is the common superclass, and yet most security-related methods throw a sizable list of subclasses of this, so that callers know exactly what kind of errors can occur, and can write handlers for specific errors, without forcing them to write a ton of catch blocks if they don't want to.

rethrow

An alternate solution is that you bundle up exceptions into your own custom type.

To do this, first write an exception (or use an existing one, but that's rarely stylistically the right move). Then, write a catch block and wrap all those weird, unrelated exceptions into this newly created one, making sure to use the 'cause' system:

public class CustomException { // find a better name
    public CustomException(String msg, Throwable cause) {
        super(msg, cause);
    }

    public CustomException(String msg) {
        super(msg);
    }

    public CustomException(Throwable cause) {
        super(cause);
    }
}

public void myMethod() throws CustomException {
    try {
        // code here
    } catch (ApiException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) {
        throw new CustomException(e);
    } catch (InvocationTargetException e) {
        throw new CustomException(e.getCause();
    }
}

but note how your suggestion that you just want to fire-and-forget is causing your API design to be problematic. For example, wrapping an InvocationTargetException like this is rather hostile to your API consumers; InvocationTargetException is itself a wrapper, so now you've got wrappers-in-wrappers-in-wrappers and that's just ugly and makes it real hard for calling code to even try to deal with problems in a pinpoint fashion. There really is no easy way around reading the APIs you use and understanding why it throws the various exceptions that it throws.

NB: If you can, the class hierarchies solution is a much better way to do this; but it does require that you are in control of the code that's throwing them.

2 of 3
0

Suppose you have:

void myMethod() throws ApiException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
          /// Your code here;
}

You can change it with:

void myMethod() throws CustomException {
       try {
          /// Your code here;
       } catch (ApiException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
         throw new CustomException(e);   // Make sure to have constructor initialized with cause.
       }
    }

E.g. CustomException class:

public class CustomException {
   CustomException(Throwable cause) {
      super(cause);
   }
}
๐ŸŒ
Programiz
programiz.com โ€บ java-programming โ€บ examples โ€บ create-custom-exception
Java Program to Create custom exception
import java.util.ArrayList; import java.util.Arrays; // create a unchecked exception class class CustomException extends RuntimeException { public CustomException(String message) { // call the constructor of RuntimeException super(message); } } class Main { ArrayList<String> languages = new ArrayList<>(Arrays.asList("Java", "Python", "JavaScript")); // check the exception condition public void checkLanguage(String language) { // throw exception if language already present in ArrayList if(languages.contains(language)) { throw new CustomException(language + " already exists"); } else { // insert