A simple exception handling library.
The goals of this project:
- Handle exceptions consistently across multiple projects.
- Flexible exception creation API.
- Simpler troubleshooting in the distributed systems.
Add the library to your project:
<dependency>
<groupId>su.piskun.exlib</groupId>
<artifactId>core</artifactId>
<version>1.0.0</version>
</dependency>
Throw an exception in the code:
throw Ex.as("Ouch!");
Customise exceptions by providing an additional context:
public Output execute(Input input) {
try {
return doCoolStuff(input);
} catch (IOException e) {
throw Ex.builder()
.message("Ouch! Something went wrong.")
.context("input", input)
.cause(e)
.build();
}
}
Throw exceptions that make sense in the HTTP context (e.g. REST API):
throw HttpEx.badRequest("email is required");
String formatting is supported as well:
throw HttpEx.notFound("user with id %s not found", id);
Currently, there are just two exception classes: Ex and HttpEx.
Both of them provide a set of convenient factory methods and the builder pattern to create an instance.
An exception has the following fields:
id: java.util.UUID
(automatically generated by the library)timestamp: java.time.Instant
(automatically generated by the library)message: java.lang.String
context: java.util.Map
cause: java.lang.Throwable
statusCode: int
(HttpEx
class only)
Add the library to your project:
<dependency>
<groupId>su.piskun.exlib</groupId>
<artifactId>spring</artifactId>
<version>1.0.0</version>
</dependency>
Import the library's config:
import su.piskun.exlib.spring.ExConfig;
@Import(ExConfig.class)
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
It will enable the ExHandler that will catch all the library's exceptions.
Note: by default the stack traces are not logged, but you can enable this feature in the application.properties
file:
logging.level.su.piskun.exlib=trace
An exception that is thrown using the following code:
throw HttpEx.notFound()
.message("Unable to find user '%s'.", username)
.context("traceId", traceId)
.context("authMethod", authMethod)
.code(ErrorCode.FAILED_LOGIN)
.build();
... can be serialized to a JSON object as follows:
{
"id": "5a9a438c-3894-4e3f-b9fe-5217e554c342",
"timestamp": "2022-08-02T16:20:51.724925378Z",
"code": "FAILED_LOGIN",
"context": {
"authMethod": "password",
"traceId": "57dad9f4-e75e-4bc2-9517-92fd070d05d4"
},
"message": "Unable to find user 'hacker@example.com'."
}
Note: the statusCode
property is not included into a serialized ExDto object intentionally, since you can get it directly from the HTTP response.
Have fun 😉