Custom Exception Handling in Quarkus REST API

In this section, we will learn how to handle exceptions in the Quarkus REST application using ExceptionMapper interface implementations. ExceptionMapper is a contract for a provider that will map a thrown application exception to a Response object.

We will show you custom exception handling with the help of a simple application,

Final Project Directory:


Complete pom.xml 

<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    https://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.knf.dev.demo</groupId>
    <artifactId>quarku-custom-exception-handling</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <properties>
        <compiler-plugin.version>3.8.1</compiler-plugin.version>
        <maven.compiler.parameters>true</maven.compiler.parameters>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <quarkus-plugin.version>2.2.3.Final</quarkus-plugin.version>
        <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
        <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
        <quarkus.platform.version>2.2.3.Final</quarkus.platform.version>
        <surefire-plugin.version>2.22.1</surefire-plugin.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>${quarkus.platform.artifact-id}</artifactId>
                <version>${quarkus.platform.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-jsonb</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-junit5</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>io.quarkus</groupId>
                <artifactId>quarkus-maven-plugin</artifactId>
                <version>${quarkus-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin.version}</version>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <configuration>
                    <systemProperties>
                        <java.util.logging.manager>
                        org.jboss.logmanager.LogManager
                        </java.util.logging.manager>
                    </systemProperties>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>native</id>
            <activation>
                <property>
                    <name>native</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <version>${surefire-plugin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                                <configuration>
                                    <systemProperties>
                                        <native.image.path>
                                        ${project.build.directory}/${project.build.finalName}-runner
                                        </native.image.path>
                                    </systemProperties>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <properties>
                <quarkus.package.type>native</quarkus.package.type>
            </properties>
        </profile>
    </profiles>
</project>

application.properties 

knowledgefactory.custom.error.msg.usernotfound = User not found
knowledgefactory.custom.error.msg.badrequest.numeric = User Id must be numeric

Declared error messages. 


Create ErrorMessage.java  

package org.knf.dev.demo.exception;

public class ErrorMessage {

private String message;
private Boolean status;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public Boolean getStatus() {
return status;
}

public void setStatus(Boolean status) {
this.status = status;
}

public ErrorMessage(String message, Boolean status) {
super();
this.message = message;
this.status = status;
}

public ErrorMessage() {
super();
}
}


Create the Custom Exception Handler 

package org.knf.dev.demo.exception;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class CustomExceptionHandler
implements ExceptionMapper<CustomException> {

@ConfigProperty(name = "knowledgefactory.custom.error.msg.usernotfound")
String userNotFound;

@Override
public Response toResponse(CustomException e) {

if (e.getMessage().equalsIgnoreCase(userNotFound)) {
return Response.status(Response.Status.NOT_FOUND).
entity(new ErrorMessage(e.getMessage(), false))
.build();
} else {

return Response.status(Response.Status.BAD_REQUEST).
entity(new ErrorMessage(e.getMessage(), false))
.build();
}
}
}


Create the Custom Exception 

package org.knf.dev.demo.exception;

import java.io.Serializable;

public class CustomException extends
RuntimeException implements Serializable {

private static final long serialVersionUID = 1L;

public CustomException() {
}

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

public CustomException(String message, Throwable cause) {
super(message, cause);
}

public CustomException(Throwable cause) {
super(cause);
}

public CustomException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {

super(message, cause, enableSuppression, writableStackTrace);
}
}


Create User Pojo 

package org.knf.dev.demo.data;

public class User {

private String name;
private String email;

public User(String name, String email) {
this.name = name;
this.email = email;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}


Create a dummy data generator 

package org.knf.dev.demo.data;

import javax.inject.Singleton;
import java.util.HashMap;
import java.util.Map;

@Singleton
public
class UserData {

public User getUserById(Long id) {
User user = genearteDummyData().get(id);
return user;
}

//Generate Dummy Users
private Map<Long, User> genearteDummyData() {
Map<Long, User> dummyUsers = new HashMap<>();
User user1 = new User("user-1", "user-1@gmail.com");
User user2 = new User("user2", "user2@gmail.com");
User user3 = new User("user3", "user3@gmail.com");
dummyUsers.put(22l, user1);
dummyUsers.put(13l, user2);
dummyUsers.put(19l, user3);
return dummyUsers;
}
}


Create the User Controller 

package org.knf.dev.demo.controller;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.knf.dev.demo.data.User;
import org.knf.dev.demo.data.UserData;
import org.knf.dev.demo.exception.CustomException;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;

@Path("/api/v1")
public class UserController {

@ConfigProperty(name = "knowledgefactory.custom.error.msg.badrequest.numeric")
String idNumericErrorMsg;

@ConfigProperty(name = "knowledgefactory.custom.error.msg.usernotfound")
String userNotFound;

@Inject
UserData userData;

@GET
@Path("/users/{id}")
public Response findUserById(@PathParam("id") String id)
throws CustomException {
Long user_id = null;
try {
user_id = Long.parseLong(id);
} catch (NumberFormatException e) {
throw new CustomException(idNumericErrorMsg);
}
User user = userData.getUserById(user_id);
if (user == null) {
throw new CustomException(userNotFound);
}
return Response.ok().
entity(userData.getUserById(user_id)).build();
}
}


Quarkus Exception Handling demo

Build application  jar file: mvn clean package

Start the application: java -jar quarkus-run.jar


Invalid Request (User Id not found): 


Invalid Request(User Id must be numeric): 


Valid request: 




More related topics,

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete