- Effective Approach for Creating Custom Exceptions in Java
- How to create custom exceptions in Java
- 1. Why do I need custom exceptions?
- 2. Writing your own exception class
- 3. Re-throwing an exception which is wrapped in a custom exception
- References:
- Other Java Exception Handling Tutorials:
- About the Author:
- How to create a custom exception type in Java? [duplicate]
- 9 Answers 9
Effective Approach for Creating Custom Exceptions in Java
We have been using handling Java custom exceptions in our code for almost every industry standard application. The usual approach is to create some custom exception classes extending the base exception handling best practice which might make more sense.
Suppose we are creating a custom exception DBException for representing the exceptions that occurred during the database-related operations. Traditionally, we create a DBException class by extending Exception class.
public class DBException extends Exception < public DBException() < super(); >public DBException(String message) < super(message); >public DBException(String message, Throwable cause) < super(message, cause); >>
Now, every time we are caught in a situation where there is a need to throw a database-related exception, we usually create an instance of DBException , put some information in form of a message and throw it.
Now, let’s consider there are following situations we have identified in which we need to throw DBException :
- SQL execution error
- No data exist where we expect at least one row
- Multiple rows exist where we expect only a single row
- Invalid parameters error
- and many more such cases
The problem with the above approach is that in catch block or in application code where these exceptions shall be handled, DBException does not provide enough information to handle each above-listed usecases, uniquely.
2. New Approach using Inner Classes
Our new approach uses static inner classes for every new exceptional scenario.
2.1. Create New Exception Types
Let’s solve the above problem with inner classes where we will create one class per use-case, and then group them inside DBException class.
Let us start with BaseException class which is created as an abstract and will be the superclass of all our exception classes.
public abstract class BaseException extends Exception < private String message; public BaseException(String msg) < super(msg); this.message = msg; >public String getMessage() < return message; >>
Now it is time to create out new Exception inner classes.
public class DBException < //SQL execution error public static class BadExecution extends BaseException < public BadExecution(String msg) < super(msg); >> //No data exist where we expect at least one row public static class NoData extends BaseException < public NoData(String msg) < super(msg); >> //Multiple rows exist where we expect only single row public static class MoreData extends BaseException < public MoreData(String msg) < super(msg); >> //Invalid parameters error public static class InvalidParam extends BaseException < public InvalidParam(String msg) < super(msg); >> >
Here, we created an inner class for each possible error scenario identified in starting. There can be many more extras. It depends on you only to identify and add more classes.
2.2. How to use custom exceptions?
Now to understand its usefulness, let’s create an exception and throw it. Then we will see the error message in the logs.
public class TestExceptions < public static void main(String[] args) < try < throw new DBExeption.NoData("No row found for id : x"); >catch(Exception e) < e.printStackTrace(); >> >
com.exception.DBExeption$NoData: No row found for id : x at com.test.TestExceptions.main(TestExceptions.java:7)
As you can see the log message in the exception stack trace has become more informative. It clearly tells what the error is. In the application code as well, you can check the instance of custom exception and handle it accordingly.
- The foremost advantage is that if the developer has written some doubtful message text, then also he can clearly observe what was actually wrong.
- You can use instance-of comparison in different situations where you handle different exceptional scenarios.
- You don’t need to send a single exception for a large set of exceptional conditions.
- It is easy to write unit test cases for negative cases where you know the exact exception class, you should expect.
- Logging is more meaningful and informative.
I hope this post about Java custom exceptions has been some information for you. If you have some suggestions, please write to me.
How to create custom exceptions in Java
In the article Getting Started with Exception Handling in Java, you know how to catch throw and catch exceptions which are defined by JDK such as IllegalArgumentException , IOException , NumberFormatException , etc.
What if you want to throw your own exceptions? Imagine you’re writing a student management program and you want to throw StudentException , StudentNotFoundException , StudentStoreException and the like?
So it’s time to create new exceptions of your own.
We will call JDK’s exceptions built-in exceptions and call our own exceptions custom exceptions.
Let me tell you this: Writing custom exceptions in Java is very easy, but the important thing is, you should ask yourself this question:
1. Why do I need custom exceptions?
The answer could be very simple: When you couldn’t find any relevant exceptions in the JDK, it’s time to create new ones of your own.
By looking at the names of the exceptions to see if its meaning is appropriate or not. For example, the IllegalArgumentException is appropriate to throw when checking parameters of a method; the IOException is appropriate to throw when reading/writing files.
From my experience, most of the cases we need custom exceptions for representing business exceptions which are, at a level higher than technical exceptions defined by JDK. For example: InvalidAgeException , LowScoreException , TooManyStudentsException , etc.
2. Writing your own exception class
- Create a new class whose name should end with Exception like ClassNameException . This is a convention to differentiate an exception class from regular ones.
- Make the class extends one of the exceptions which are subtypes of the java.lang.Exception class. Generally, a custom exception class always extends directly from the Exception class.
- Create a constructor with a String parameter which is the detail message of the exception. In this constructor, simply call the super constructor and pass the message.
public class StudentNotFoundException extends Exception < public StudentNotFoundException(String message) < super(message); >>
And the following example shows the way a custom exception is used is nothing different than built-in exception:
public class StudentManager < public Student find(String studentID) throws StudentNotFoundException < if (studentID.equals("123456")) < return new Student(); >else < throw new StudentNotFoundException( "Could not find student with ID " + studentID); >> >
public class StudentTest < public static void main(String[] args) < StudentManager manager = new StudentManager(); try < Student student = manager.find("0000001"); >catch (StudentNotFoundException ex) < System.err.print(ex); >> >
StudentNotFoundException: Could not find student with ID 0000001
3. Re-throwing an exception which is wrapped in a custom exception
It’s a common practice for catching a built-in exception and re-throwing it via a custom exception. To do so, let add a new constructor to our custom exception class. This constructor takes two parameters: the detail message and the cause of the exception. This constructor is implemented in the Exception class as following:
public Exception(String message, Throwable cause)
Besides the detail message, this constructor takes a Throwable ’s subclass which is the origin (cause) of the current exception. For example, create the StudentStoreException class as following:
public class StudentStoreException extends Exception < public StudentStoreException(String message, Throwable cause) < super(message, cause); >>
public void save(Student student) throws StudentStoreException < try < // execute SQL statements.. >catch (SQLException ex) < throw new StudentStoreException("Failed to save student", ex); >>
Here, suppose that the save() method stores the specified student information into a database using JDBC. The code can throw SQLException . We catch this exception and throw a new StudentStoreException which wraps the SQLException as its cause. And it’s obvious that the save() method declares to throw StudentStoreException instead of SQLException .
So what is the benefit of re-throwing exception like this?
Why not leave the original exception to be thrown?
Well, the main benefit of re-throwing exception by this manner is adding a higher abstraction layer for the exception handling, which results in more meaningful and readable API. Do you see StudentStoreException is more meaningful than SQLException , don’t you?
However, remember to include the original exception in order to preserve the cause so we won’t lose the trace when debugging the program when the exception occurred.
And the following code demonstrates handling the StudentStoreException above:
StudentManager manager = new StudentManager(); try < manager.save(new Student()); >catch (StudentStoreException ex)
References:
Other Java Exception Handling Tutorials:
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.
How to create a custom exception type in Java? [duplicate]
Can some of the answers please discuss checked vs. unchecked exceptions? What does extending Exception imply? RuntimeException? Throwable?
There is 1) creating a custom exception type/class (as shown so many times) and 2) raising the exception. To raise an exception, simply pass the appropriate instance to throw , normally: throw new MyFormatExpcetion(«spaces are not allowed»); — you could even use the standard ParseException, without «creating» a custom exception type.
See video tutorials about exception class creation and handling in Java. bitspedia.com/2013/11/exception-handling-in-java-video.html
9 Answers 9
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); >>
try < if(word.contains(" ")) < throw new WordContainsException(); >> catch(WordContainsException ex) < // Process message however you would like >
This was just the declaration for the exception, it can be thrown with a simple throw new WordContainsException(); Updated and added usage.
You seem to already have the catch within your code, I’m not sure exactly where you want the exception to be thrown. You could put it before the catch section, or inside of it. I edited it assuming how you might want to use the exception
You should add two more constructors ( WordContainsException(Throwable) and WordContainsException(String, Throwable) ) to properly support exceptions chaining
@DaniloPiazzalunga you don’t need to support exception chaining unless you’re using exception chaining.
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.