Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling DataIntegrityViolationExceptions in Spring Data REST

Let's say I have Airport entity with attribute:

@Column(nullable = false, unique = true)
private final String code;

Obviously, when I persist entity with code I used before, it would throw DataIntegrityViolationException

I have Spring Boot app with Spring Data REST enabled.

For such situations, there isRepositoryRestExceptionHandler to handle DataIntegrityViolationExceptions and map them to 409 status code:

@ExceptionHandler({ OptimisticLockingFailureException.class, DataIntegrityViolationException.class })
ResponseEntity<ExceptionMessage> handleConflict(Exception o_O) {
    return errorResponse(HttpStatus.CONFLICT, new HttpHeaders(), o_O);
}

Typical response would look like as follows:

HTTP/1.1 409
X-Application-Context: application
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 28 Apr 2017 10:21:31 GMT

{
  "cause" : {
    "cause" : {
      "cause" : null,
      "message" : "Unique index or primary key violation: \"UK_X9RMMVEVTW274QQXGT73OQ74_INDEX_C ON PUBLIC.AIRPORT(CODE) VALUES ('null', 54)\"; SQL statement:\ninsert into AIRPORT (id, rec_version, code, description) values (null, ?, ?, ?) [23505-194]"
    },
    "message" : "could not execute statement"
  },
  "message" : "could not execute statement; SQL [n/a]; constraint [\"UK_X9RMMVEVTW274QQXGT73OQ74_INDEX_C ON PUBLIC.AIRPORT(CODE) VALUES ('null', 54)\"; SQL statement:\ninsert into AIRPORT (id, rec_version, code, description) values (null, ?, ?, ?) [23505-194]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
}

The question is whether it is good approach to sprinkle responses with SQL exceptions. In my opinion it's not.

If not, what are good practices to follow and how to implement them in Boot and Data REST?

like image 966
Patrik Mihalčin Avatar asked Oct 30 '22 08:10

Patrik Mihalčin


1 Answers

Whether it is good approach to sprinkle responses with SQL exceptions?

In most cases, it is preferred to convert such exceptions into a custom error-message/ error-code before send it to client-app.

What are good practices to follow and how to implement them in Boot and Data REST?

In spring-boot & REST, you can implement your own ExceptionController/ExceptionHandler for such type of exception hanlding. Here you can catch any type of exception, and can convert it any form of custom object.

For example:

@ControllerAdvice
@RestController
public class ExceptionController {

@ExceptionHandler(value = Exception.class)
public ResponseEntity<?> handleException(Exception e) {
    UserResponse response = null;

    if(e instanceof DataIntegrityViolationException){
        DataIntegrityViolationException ex = (DataIntegrityViolationException) e;
        response = new UserResponse(ErrorCodes.DuplicateMobNo, "This mobile no is already Registered!");
        return new ResponseEntity<UserResponse>(response, HttpStatus.CONFLICT);
    }
}

Where UserResponse can be something like this:

public class UserResponse extends GenericResponse{

    private Long customErrorCode;
    private String errorMsg;

public UserResponse() {

}

    public UserResponse(Long code, String msg) {
        this.customErrorCode = code;
        this.errorMsg = msg;
    }

    public String getCustomErrorCode () {
        return customErrorCode ;
    }

    public void setCustomErrorCode (Long customErrorCode ) {
        this.customErrorCode = customErrorCode ;
    }

    public String getErrorMsg  () {
        return errorMsg ;
    }

    public void setErrorMsg  (String errorMsg ) {
        this.errorMsg = errorMsg ;
    }
}

You can create your own custom Error code like DuplicateMobileNo and so

like image 76
Afridi Avatar answered Nov 15 '22 11:11

Afridi