Semana 05: Error Handling
En una típica división de código en las capas de controller, service & repository.
¿Quién es el responsable?
Extracción de una cuenta de banco con saldo negativo
No se respeta una regla de negocio entre 2 instancias de un modelo
Se produce un timeout contra otro servidor por fallo de red
No se pudo realizar un INSERT de mi entidad con un ID ya existente en la base de datos
Error al adquirir la conexión contra la base de datos
Recibimos un atributo que no posee nuestra entidad (*)
Nos envían un JSON mal formado
¿División por cero? ¿Objeto Nulo? ¿Intentar hacer comparaciones de valores entre 2 objetos donde uno es nulo?
@ResponseStatus
Podemos crear excepciones anotadas, para que al tirarlas desde un controller, se retorne el status code HTTP que pasemos por parámetro:
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Song not found")
public class SongNotFoundException extends RuntimeException {
}
@ResponseStatusException
Es una alternativa a @ResponseStatus. Al realizar el throw de esta clase, se corta el flujo de nuestra app.
@GetMapping("/song/{id}")
public Song getSong(@PathVariable("id") Long id) {
try {
return songService.getSong(id);
} catch (SongNotFoundException exception) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND,
"Song Not Found", exception);
}
}
En este caso, además, estamos mapeando una excepción de dominio (SongNotFoundException) a una excepción del controller (404 NOT FOUND).
@ExceptionHandler
Esta annotation nos permite referir a excepciones desde otras capas:
@ExceptionHandler(SongNotFound.class)
public void conflict() {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Song Not Found");
}
La desventaja es que solo funciona para un controller (*)
@ExceptionHandler
Esta annotation nos permite referir a excepciones desde otras capas:
@ExceptionHandler(SongNotFound.class)
public ResponseEntity<String> conflict() {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Ocurrió un error");
}
La desventaja es que solo funciona para un controller (*)
@RestControllerAdvice
Permite centralizar uno o más @ExceptionHandler en una misma clase.
@RestControllerAdvice
public class PersonaExceptionHandler {
@ExceptionHandler(value = {PersonaNameBad.class})
protected ResponseEntity<ErrorMessage> handleConflict(RuntimeException ex) {
return ResponseEntity
.status(HttpStatus.NOT_ACCEPTABLE)
.body(new ErrorMessage("Bad Code", HttpStatus.NOT_ACCEPTABLE.toString()));
}
}
Implemente 2 excepciones en los siguientes métodos:
- Búsqueda de una canción por identificador.
- Otro método implementado en el Lab 2.01