# Java Full Stack Spring boot & React app: Backend REST API / 4 - Exception handling

Hello,

In [this previous tutorial](https://wilkom2009.hashnode.dev/java-fullstack-backend-rest-api-spring-security-and-jwt-b), we secured our backend RESTful API using Spring Security and JWT. Now we are going to handle errors/exceptions in the RESTful API.

# Problem

Until now, all eventual error messages thrown in our RESTful API are not user-friendly. For example, when you try to log in with invalid credentials, you should have a similar message in Postman:


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629144745136/5kgoed6AD.png)

In the following lines, we'll use one of the smart solutions [Spring](https://spring.io/) provides to make the API throw understandable error messages.
 
# Solution: Spring Global Exception Handling

###  1 - ExceptionResponse.java

This java class will be the custom error message class to return by the API when an error occurs. Create it in the *com.codeurinfo.easytransapi.exception* package.


```
package com.codeurinfo.easytransapi.exception;

import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;
import org.springframework.http.HttpStatus;

public class ExceptionResponse {

  private HttpStatus status;

  @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
  private LocalDateTime timestamp;

  private String message;
  private String description;

  public ExceptionResponse() {
    this.timestamp = LocalDateTime.now();
  }

  public ExceptionResponse(HttpStatus status) {
    this();
    this.status = status;
    this.message = "An error occured";
  }

  public ExceptionResponse(String message) {
    this();
    this.message = message;
  }

  public ExceptionResponse(HttpStatus status, String message, Throwable ex) {
    this();
    this.status = status;
    this.message = message;
    this.description = ex.getLocalizedMessage();
  }

  public LocalDateTime getTimestamp() {
    return this.timestamp;
  }

  public void setTimestamp(LocalDateTime timestamp) {
    this.timestamp = timestamp;
  }

 // getters and setters
  
}

``` 

### 2 - GlobalControllerExceptionHandler.java

Let's create this class in *com.codeurinfo.easytransapi.exception* package to handle all the errors in the RESTful API.


```
package com.codeurinfo.easytransapi.exception;

import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalControllerExceptionHandler {

  @ExceptionHandler({ DataIntegrityViolationException.class })
  @ResponseStatus(value = HttpStatus.CONFLICT)
  public ExceptionResponse handleDIVException(
    DataIntegrityViolationException e
  ) {
    return new ExceptionResponse(
      HttpStatus.CONFLICT,
      "Data integrity error.",
      e
    );
  }

  @ExceptionHandler({ Exception.class })
  @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
  public ExceptionResponse handleException(Exception e) {
    return new ExceptionResponse(
      HttpStatus.INTERNAL_SERVER_ERROR,
      e.getLocalizedMessage(),
      e
    );
  }

  @ExceptionHandler({ AccessDeniedException.class })
  @ResponseStatus(value = HttpStatus.FORBIDDEN)
  public ExceptionResponse handleForbiddenException(AccessDeniedException e) {
    return new ExceptionResponse(
      HttpStatus.FORBIDDEN,
      e.getLocalizedMessage(),
      e
    );
  }


}

``` 
- Spring [@RestControllerAdvice](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RestControllerAdvice.html) annotation is used on a global class to make all its methods annotated with [@ExceptionHandler](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html) be accessible across all the controllers in the RESTful API.

- [@ExceptionHandler](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html) annotation is used upon methods to handle specific Exceptions.
- Thus, we use *@ExceptionHandler({ DataIntegrityViolationException.class })* on the **handleDIVException** method to handle all DataIntegrityViolation Exceptions occurred in @RepositoryRestResource annotated repository interfaces.

- *@ResponseStatus* is used to send the corresponding HTTP status code for the JSON response.

- For unknown exceptions handling, we use *@ExceptionHandler({ Exception.class })* on the **handleException** method and provide a *HttpStatus.INTERNAL_SERVER_ERROR* status code to return.

- Similarly, we use *@ExceptionHandler({ AccessDeniedException.class })* and provide *HttpStatus.FORBIDDEN* on the **handleForbiddenException** method  to handle URL access denied exception.

### 3 - Tests

1 - Log in with bad credentials

- POST request : *http://localhost:8000/api/auth/login*
- Body: 

```
{
	"userName": "user",
    "password": "user1"
}
``` 
- Response

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629152330015/klCsSU88E.png)

2 - Try to access an unauthorized resource

Suppose you logged in with *user/user* good credentials, following our API logic, a user with username **user** is not allowed to make a **routeByName** search request

- POST request: *http://localhost:8000/api/routes/search/routesByName?name=Rex-Adidogome*
- Provide Authorization token value (token generated when log in was successful)
- Response

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629152812140/YWP3-AczB.png)

In the next post, we'll add new features to our EasyTrans app. Hope you learned something new. If so, don't forget to hit the Like button and subscribe to this blog to be up to date with new posts.

