Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot exception handling best practice

I have a simple question about exception handling. I currently have an application divided into multiple layers: controller, service, repository, and my question is the following: the exception handling should be done by the controller or the service?

Example:

Controller:

@PostMapping(value = "/{id}/parents", produces = "application/json; charset=utf-8")
public ResponseEntity<AccommodationRequestDTO> resident(@PathVariable Long id, @Valid @RequestBody ParentsAndUrgencyContactDTO parentsAndUrgencyContactDTO) {
    AccommodationRequestDTO saved;
    try {
        saved = this.service.parents(id, parentsAndUrgencyContactDTO);
    } catch (Exception e) {
        throw new ResponseStatusException(
                HttpStatus.INTERNAL_SERVER_ERROR,
                "Failed to save request", e);
    }
    return ResponseEntity.ok(saved);
}

Service:

public AccommodationRequestDTO parents(Long id, ParentsAndUrgencyContactDTO parentsAndUrgencyContactDTO) {
    Optional<AccommodationRequest> accommodationRequest = repository.findById(id);

    if (accommodationRequest.isPresent()) {
        AccommodationRequest saved = accommodationRequest.get();
        Parent firstParent = parentMapper.toEntity(parentsAndUrgencyContactDTO.getFirstParent());
        Parent secondParent = parentMapper.toEntity(parentsAndUrgencyContactDTO.getSecondParent());

        firstParent = parentRepository.save(firstParent);
        secondParent = parentRepository.save(secondParent);

        saved.setFirstParent(firstParent);
        saved.setSecondParent(secondParent);
        saved = this.repository.save(saved);

        return mapper.toDTO(saved);
    } else {
        throw new ResponseStatusException(
                HttpStatus.NOT_FOUND, " with id " + id + " not found !");
    }

}

What is the best practice, should I remove my try-catch from the controller and put it in my service? Because with this code my 404 Exception is overridden by the controller catch.

like image 789
Spialdor Avatar asked Apr 23 '26 07:04

Spialdor


1 Answers

If you want to throw a exception throw it in service layer.

It will be better to define one more package named exception.

and have your custom exception, exception response and exception handler in it.

My code structure looks like:

package com.***.demo.exception;

public class DataNotFound extends EntityNotFoundException {
    public DataNotFound(String message) {
        super(message);
    }
}
package com.***.demo.exception;

@Data
@AllArgsConstructor
public class ErrorDetails {
    private Date timestamp;
    private String message;
    private String details;
}
package com.***.demo.exception;

@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(DataNotFound.class)
    public ResponseEntity<?> dataNotFoundExceptionHandling(Exception exception, WebRequest request) {
        return new ResponseEntity<>(new ErrorDetails(new Date(), exception.getMessage(), request.getDescription(false)), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<?> globalExceptionHandling(Exception exception, WebRequest request) {
        return new ResponseEntity<>(new ErrorDetails(new Date(), exception.getMessage(), request.getDescription(false)), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

Hope you got your answer.

like image 128
krishnkant jaiswal Avatar answered Apr 26 '26 04:04

krishnkant jaiswal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!