How to create custom exceptions in java with example

An Exception is an undesirable state which arises out of some unexpected condition or scenario which was not handled during application development or due to some unexpected circumstances arising in the execution environment.
Java provides support for handling exception conditions during application execution using trycatch blocks.

Exceptions in java are categorized into two parts :
Checked Exceptions
Exceptions which need to be declared or handled during application development are checked exceptions. They are called checked because their appropriate handling is checked at compile time by the compiler.
Handling implies either they are caught in a try-catch block or are declared to be thrown (using throws keyword), if not caught. If either of these two is not done, then the compiler does not allow the application to compile.
In technical and implementation terms, checked exceptions are those which extend java.lang.Exception class.
Examples of checked exceptions are
1. java.io.FileNotFoundException,
2. java.io.IOException,
3. java.sql.SQLException,
4. java.lang.IllegalAccessExceptionetc.
Unchecked Exceptions
These exceptions need not be declared or handled by the application as they arise due to unpredicted conditions and not due to absence of programmatic handling.
For example, Memory shortage resulting in java.lang.OutOfMemoryError.
In technical and implementation terms, unchecked exceptions are those which extend java.lang.RuntimeException class.
Examples of unchecked exceptions are java.lang.NullPointerException,java.lang.ArrayIndexOutOfBoundsException, java.lang.OutOfMemoryError etc.
Why Custom Exceptions?
Exceptions will arise during application execution and should be thrown and logged to figure out the root cause of the problem.
But there comes a question “What is the need to define a custom or creating your own exception when there are already built in exceptions in java?”.
The answer lies in below scenarios :

    1. An application method throws many exceptions and your design says not to handle them but to throw them to propagate upwards.
      Will it be a good idea to throw and catch all exceptions from all the methods coming in the propagation channel or have one exception which wraps all these exceptions and throw that one exception and catch that single exception.
      Suppose your method accesses another class method using Reflection, then it will have atleast 5 catch blocks of various exceptions. Now you declare this method to throw all these 5 exceptions and catch them in the calling method as :

         void myMethod() throws Exception1, Exception2, 
                        Exception3, Exception4, Exception5 {
              try {
                  // risky code
              } catch(Exception1 e) {
                   throw e;
              } catch(Exception2 e) {
                   throw e;
              } catch(Exception3 e) {
                   throw e;
              } catch(Exception4 e) {
                   throw e;
              } catch(Exception5 e) {
                   throw e;
              }
        }
      

      Besides you need to have all these 5 catch blocks in the method which calls the above method and re-declare that method to throw all these 5 exceptions or you create just 1 exception and wrap all those 5 exceptions and throw only your custom exception as :

         void myMethod() throws MyException { // declare only one exception
              try {
                  // risky code
              } catch(Exception1 e) {
                   throw new MyException(e);
              } catch(Exception2 e) {
                   throw new MyException(e);
              } catch(Exception3 e) {
                   throw new MyException(e);
              } catch(Exception4 e) {
                   throw new MyException(e);
              } catch(Exception5 e) {
                   throw new MyException(e);
              }
        }
      

      In this case, the calling method needs to have just 1 catch block and declare just 1 exception to throw. Its up to you to decide which is better.

    2. You don’t want your application to expose the underlying logic and the exact error reason generated by the JVM which may be misleading in some cases.
      For example, when converting an object to XML using JAXB you might get an error like javax.xml.bind.JAXBException: class is not known to this context.
      Instead of exposing the usage of JAXB, it may be preferable to show com.codippa.XMLConversionException: Unable to generate XML due to <your reason>.
    3. Creating custom exception always gives you the flexibility to add your own handling to the exception and use your own logging messages when an exception arises.
    4. It always looks professional when your own application specific exception appears in stacktrace logs. It would always be better to see an error like com.codippa.error.PostNotFoundException: Invalid Post Name rather than java.lang.ArrayIndexOutOfBoundException: 3.
How to create Custom Checked Exceptions
Checked exceptions are sub-classes of java.lang.Exceptionas stated above. So in order to create your own exception class, follow below couple of steps:
1. Create a class with desired exception name
2. Make it the child class of java.lang.Exception.
You can also add relevant constructors to it such as one accepting a String for the error message and another one that accepts an exception object.
Below code shows custom checked exception example which also shows various constructors that can be added to it and their requirement.

public class CodippaException extends Exception {
   
     /*
      * Required when you want to add a custom message 
      * when throwing the exception
      * as throw new CodippaException("No post found");
      */
      public CodippaException(String message) {
        // calling super invokes the constructors of 
        // all super classes which helps to create the 
        // complete stacktrace 
	super(message);
      }
     /*
      * Required when you want to wrap the exception 
      * generated inside the catch block and rethrow it
      * as catch(FileNotFoundException e) { 
      *    throw new CodippaException(e);
      * }
      */
     public CodippaException(Throwable cause) {
        // call appropriate parent constructor		
        super(cause);
     }
    /*
     * Required when you want both the above 
     * as catch(FileNotFoundException e) { 
     *    throw new CodippaException(e, "File not found");
     * }
     */
     public CodippaException(String message, Throwable throwable) {
       // call appropriate parent constructor 
       super(message, throwable);
     }
}

How to create Custom Unchecked(Runtime) Exceptions
Checked exceptions are sub-classes of java.lang.RuntimeException. So in order to create your own unchecked exception class,
1. Create a class with desired name, and
2. Make it the child class of java.lang.RuntimeException. Further, to add more functionality add relevant constructors to it.
Below code shows custom unchecked exception example which also shows various constructors that can be added to it and their requirement.

public class CodippaException extends RuntimeException {
     /*
      * Required when you want to add a custom message
      * when throwing the exception
      * as throw new CodippaException("No post found");
      */
     public CodippaException(String message) {
       // calling super invokes the constructors of all super classes 
       // which helps to create the complete stacktrace 
       super(message);
     }
    
     /*
      * Required when you want to wrap the exception generated 
      * inside the catch block and rethrow it
      * as catch(ArrayIndexOutOfBoundsException e) { 
      *    throw new CodippaException(e);
      * }
      */
     public CodippaException(Throwable cause) {
        // call appropriate parent constructor		
        super(cause);
     }
   
     /*
      * Required when you want both the above 
      * as catch(ArrayIndexOutOfBoundsException e) { 
      *    throw new CodippaException(e, "File not found");
      * }
      */
     public CodippaException(String message, Throwable throwable) {
        // call appropriate parent constructor 
	super(message, throwable);
     }
}
Let’s tweak in

  1. java.lang.RuntimeException is a super class for all unchecked exceptions but itself is a child class of java.lang.Exception which in turn is the super class of all checked exceptions.
  2. You don’t need to declare or throw Unchecked exceptions and there will be no compilation error for that.
  3. It is NOT necessary to define all the constructors in your custom exception class illustrated above. Use only those which are required by your application.
  4. java.lang.Throwable is the parent class of the java exception hierarchy and is the super class of java.lang.Exception.
  5. Calling super() from a custom exception class constructor helps to prepare the entire stacktrace. Method for this is written in java.lang.Throwable class.

Learnt a bit about custom Exceptions. Play around with your own!!! Buzz here for any queries / clarifications and do not forget to click the clap.

Leave a Reply