Exception Translation with ET
Learn how to do exception translation with AspectJ using the ET (exception translation) library and it's lighter Java 8 approach.
Join the DZone community and get the full member experience.
Join For FreeSome time ago I wrote a small blog post about exception translation with AspectJ. In this blog post we will see how to accomplish the same using ET and its lighter Java 8 approach.
Motivation
Exception translation (or exception conversion) is the process of converting one type of exception into another.
The Java code to translate an exception is quite simple and I think every Java developer writes something like this from time to time:
try {
// code that can throw FooException
} catch(FooException e) {
// convert FooException to BarException
throw new BarException(e);
}
Exception translation is typically applied if exceptions from third party libraries do not fit into your application. Reasons for this might be:
- Exceptions thrown by a library are too low level and/or you do not want to leak implementation details into other parts of your application. For example, you want to use a more genericDataAccessException instead of a lower level SQLException.
- A library is using checked exception while you prefer using only runtime exception in your application.
Exception Translation with ET
ET is a small and simple library for exception translation. To get started with ET, you just need to add the following dependency to your code:
<dependency>
<groupId>com.mscharhag</groupId>
<artifactId>et</artifactId>
<version>0.2.0</version>
</dependency>
ET makes use of Java 8 features, so do not forget to set your compiler Level to Java 8.
We start with configuring an ExceptionTranslator instance:
ExceptionTranslator et = ET.newConfiguration()
.translate(IOException.class).to(MyRuntimeException.class)
.translate(FooException.class, BarException.class).to(BazException.class)
.done()
Here we create an ExceptionTranslator that converts IOException, FooException andBarException. IOException will be translated to MyRuntimeException while FooException andBarException are translated to BazException.
Please note that ET requires the translation target exceptions (here MyRuntimeException andBazException) to be RuntimeExceptions.
ExceptionTranslator instances are thread safe and immutable. It is safe to configure anExceptionTranslator once and then make it globally available.
Now we can use our new ExceptionTranslator to wrap the code that can throw exceptions we want to convert.
et.withTranslation(() -> {
// can throw IOException, FooException and/or BarException
myObject.dangerOperation();
});
f now an IOException is thrown by dangerOperation()et will catch it. et then throws a newMyRuntimeException from the caught IOException. The original IOException is stored in the causefield of MyRuntimeException.
To return a value from a translation block withReturningTranslation() can be used:
MyResultClass data = et.withReturningTranslation(() -> {
...
return myObject.dangerOperation();
});
Summary
ET is a small library that might be useful to you, if you have to do a lot of exception conversion in your code. After configuring your conversion rules once, exceptions can be converted by simply wrapping the code in a lambda expression.
Have a look at the full ET documentation on GitHub.
Published at DZone with permission of Michael Scharhag, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments