Hi have a simple spring controller that returns ResponseStatusException in case of error.
@RestController
@RequestMapping("/process")
public class ProcessWorkitemController {
@Autowired MyService service;
@GetMapping("/{id}")
public ResponseEntity<?> findById(@PathVariable Long id) {
Optional<MyObj> opt = service.getObj(id);
opt.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, String.format("Process id %s not found", id), null));
return ResponseEntity.ok(opt.get());
}
}
This works perfctely if invoked with SoapUI: it shows me a Json as follows:
{
"timestamp": "2021-01-20T10:59:48.082+0000",
"status": 404,
"error": "Not Found",
"message": "Process id 1 not found",
"path": "/workspace-manager/process/1"
}
When I call the same service with the browser it shows the whitelabel error page with my custmo error message.
I want a JSON as response even on the browser, is this possible?
Thanks in advance.
I would avoid using ResponseStatusException, especially when building an application that needs a unified way of handling exceptions. What I would do instead is the following:
@RestControllerAdvice. This will effectively be the main entrypoint for exception handling of your app.A simple example is the following (disregard the inner classes -- only there in order to save space).
@RestControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(ServiceException.class)
public ResponseEntity<ExceptionResponse> handleException(ServiceException e) {
return ResponseEntity
.status(e.getStatus())
.body(new ExceptionResponse(e.getMessage(), e.getStatus().value()));
}
public static class ExceptionResponse {
private final String message;
public String getMessage() { return message; }
private final Integer code;
public Integer getCode() { return code; }
public ExceptionResponse(String message, Integer code) {
this.message = message;
this.code = code;
}
}
}
package com.ariskourt.test.controllers;
import org.springframework.http.HttpStatus;
public abstract class ServiceException extends RuntimeException{
public ServiceException(String message) {
super(message);
}
public abstract HttpStatus getStatus();
}
@RestController
@RequestMapping("/process")
public class ProcessController {
@GetMapping("/{id}")
public ResponseEntity<?> findById(@PathVariable Long id) {
return Optional
.of(1L)
.filter(number -> number.equals(id))
.map(ResponseEntity::ok)
.orElseThrow(() -> new ProcessNotFoundException(String.format("Process with id %s not found", id)));
}
}
With all that in place, you should a unified way of handling exceptions which also always returns the correct message not matter the client.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With