How to Create Custom Exception in Java

In this post, we'll explore how to create and use custom exceptions in Java.

What will we learn?

  1. Steps to create custom exceptions
  2. How to create checked custom exceptions with examples?
  3. How to create an unchecked custom exception with examples?
  4. More examples
Although Java’s built-in exceptions handle the most common errors, you will probably want to create your own exception types to handle situations specific to your applications.

Java provides us with a rich set of built-in exceptions. However, sometimes our application requires exceptions to handle situations specific to your applications. Java allows us to create our own exception classes to represent custom problem cases.

Steps to Create a Custom Exception

Here are the steps to create a custom exception:

1. Decide the Exception Type: 

Decide whether your exception should be checked or unchecked.

Checked Exceptions: These are the exceptions that a method can throw but cannot handle on its own. Any method that might throw a checked exception must either handle it using a try-catch block or declare it using the throws keyword. 

Unchecked Exceptions: These are the exceptions that can be thrown during the execution of the program but were not anticipated. They extend RuntimeException and don't need to be declared or caught. 

2. Choose a Meaningful Name: 

Your custom exception name should typically end with "Exception" to maintain clarity and adhere to Java's naming convention. 

3. Extend the Appropriate Exception Class: 

For checked exceptions, extend the Exception class. 
For unchecked exceptions, extend the RuntimeException class. 

4. Create Constructors: 

To give more context or customization ability to your exception, create constructors for it. At a minimum, you should provide:
  • A default constructor. 
  • A constructor that takes a string parameter for the error message. 
  • Additional constructors as required (e.g., to initialize custom fields). 

5. (Optional) Add Custom Fields and Methods: 

If you want your exception to hold additional information or provide specific functionalities, you can add custom fields and methods.

Below are examples of custom exceptions:

InvalidAgeException
ResouceNotFoundException
BadRequestException
UnauthorizedRequestException etc.

Now, we will discuss how to create checked and unchecked custom exceptions with examples. 

Custom Checked Exception

If the client is able to recover from the exception, make it a checked exception. To create a custom-checked exception, just create a class that extends java.lang.Exception:
public class ResourceNotFoundException extends Exception {
    private static final long serialVersionUID = 1L;

    public ResourceNotFoundException(Object resourId) {
        super(resourId != null ? resourId.toString() : null);
    }
}
How to use ResourceNotFoundException custom exception in applications?
public class TestResourceNotFoundException {
    public static void main(String[] args) throws ResourceNotFoundException {
         ResourceManager manager = new ResourceManager();
         manager.getResource(0);
    }
}

class Resource {
    private int id;

    public Resource(int id) {
        super();
        this.id = id;
    }
}

class ResourceManager {
    public Resource getResource(int id) throws ResourceNotFoundException {
        if (id == 10) {
             new Resource(id);
        } else {
             throw new ResourceNotFoundException("Resource not found with id ::" + id);
        }
        return null;
    }
}

class ResourceNotFoundException extends Exception {
    private static final long serialVersionUID = 1L;

    public ResourceNotFoundException(Object resourId) {
        super(resourId != null ? resourId.toString() : null);
    }
}
Output :
Exception in thread "main" com.ramesh.corejava.devguide.exceptions.customexceptions.ResourceNotFoundException: Resource not found with id ::0
 at com.ramesh.corejava.devguide.exceptions.customexceptions.ResourceManager.getResource(TestResourceNotFoundException.java:26)
 at com.ramesh.corejava.devguide.exceptions.customexceptions.TestResourceNotFoundException.main(TestResourceNotFoundException.java:6)

Custom Unchecked Exception

If the client cannot do anything to recover from the exception, make it an unchecked exception. To create a custom unchecked exception, just create a class that extends java.lang.RuntimeException.
public class BaseRuntimeException extends RuntimeException {
  
    private static final long serialVersionUID = 1L;

    private int statusCode = 500;

    public BaseRuntimeException() {
        super();
    }

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

    public BaseRuntimeException(BaseException be) {
        super(be.getMessage(),be);
        this.statusCode = be.getErrorCode();
    }

    public BaseRuntimeException(Throwable t) {
        super(t.getMessage(),t);
    }

    public BaseRuntimeException(String message, Throwable t) {
        super(message, t);
    }

    public BaseRuntimeException(int status, String message, Throwable t) {
        super(message, t);
        this.statusCode = status;
    }

    public BaseRuntimeException(String message, Throwable t,
            boolean enableSuppression, boolean writableStackTrace) {
        super(message, t, enableSuppression, writableStackTrace);
    }

    public int getStatusCode() {
        return statusCode;
    }
}
How to use BaseRuntimeException custom exception in applications.
public class TestRunTimeException {
    public static void main(String[] args) {
        List<String> data = new ArrayList<>(Collections.nCopies(100, "Ramesh"));
        processData(data);
    }
 
    public static void processData(List<String> data){
        if(data.size() > 50){
             throw new BaseRuntimeException("Image file size con't exceed :: " + 10000000);
        }
    }
}
Output:
Exception in thread "main" com.ramesh.corejava.devguide.exceptions.customexceptions.BaseRuntimeException: Image file size con't exceed :: 10000000
 at com.ramesh.corejava.devguide.exceptions.customexceptions.TestRunTimeException.processData(TestRunTimeException.java:15)
 at com.ramesh.corejava.devguide.exceptions.customexceptions.TestRunTimeException.main(TestRunTimeException.java:10)

More Examples

Few Custom Exceptions that I personally have been using in my day-to-day project work. 

BadRequestException Custom Exception

BadRequestException custom exception is thrown by the service layer when a request parameter is wrong.
public class BadRequestException extends Exception {
    private static final long serialVersionUID = 1L;

    public BadRequestException() {
        super();
    }

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

    public BadRequestException(String message, Throwable t) {
        super(message, t);
    }

    public BadRequestException(Throwable t) {
        super(t);
    }
}

ResourceNotFoundException Custom Exception

ResourceNotFoundException custom exception is thrown by the service layer when the resource requested is not found.
public class ResourceNotFoundException extends Exception {
    private static final long serialVersionUID = 1L;

    public ResourceNotFoundException(Object resourId) {
        super(resourId != null ? resourId.toString() : null);
    }
}

UnauthorizedRequestException Custom Exception

UnauthorizedRequestException custom exception is thrown by the service layer when a request parameter is wrong or the user is unauthorized.
public class UnauthorizedRequestException extends Exception {
    private static final long serialVersionUID = 1L;

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

Best Practices

  • Use meaningful names for your custom exception classes. 
  • Document the exception using JavaDoc to explain when and why this exception might be thrown.
  • Remember, checked exceptions (like the one above) must be either caught or declared in the method signature using the throws keyword. If you don't want this obligation, your custom exception should extend RuntimeException (making it unchecked). 

Conclusion

Custom exceptions are a powerful feature in Java, allowing developers to signal error conditions specific to their applications in a clear and standard manner. Using them can help in creating more readable, maintainable, and robust code.

Comments