Я хочу реализовать пользовательские страницы ошибок для кодов ошибок с сообщениями. Следуя инструкциям baeldung, я получил это на бэкэнде:
Пользовательское исключение:
public class TicketNotFoundException extends RuntimeException
{
public TicketNotFoundException(Long id)
{
super("Ticket not found with id: "+id);
}
}
Пользовательский ответ:
public class CustomErrorResponse
{
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
private LocalDateTime timestamp;
private int status;
private String error;
//getters setters
}
Пользовательский обработчик исключений:
@ControllerAdvice
public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler
{
@ExceptionHandler(value = TicketNotFoundException.class)
public ResponseEntity<CustomErrorResponse> customHandleNotFound(Exception ex)
{
CustomErrorResponse errors = new CustomErrorResponse();
errors.setTimestamp(LocalDateTime.now());
errors.setError(ex.getMessage());
errors.setStatus(HttpStatus.NOT_FOUND.value());
return new ResponseEntity<>(errors, HttpStatus.NOT_FOUND);
}
}
И сам ответ работает:
{отметка времени: «2020-04-13 09:33:52», статус: 404, ошибка: «Билет не найден с идентификатором: 1» }
Внутренний терминал:
Resolved [com.eggorko.ebt.ticket.TicketNotFoundException: Ticket not found with id: 1]
Итак, мой вопрос: что мне делать на стороне клиента?
Контроллер клиента выглядит следующим образом:
@GetMapping("/{id}")
public String ticket(@PathVariable Long id, Model model)
{
String url = "http://localhost:8080/api/ticket/";
ResponseEntity<Ticket> ticket = restTemplate.getForEntity( url+ id, Ticket.class);
model.addAttribute("ticket",ticket.getBody());
model.addAttribute("title","Tickets");
return "ticket";
}
Я сделал этот бит на стороне клиента, но он не работает:
@Controller
public class MyErrorController implements ErrorController
{
@RequestMapping("/error")
public String handleError(HttpServletRequest request)
{
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
Integer statusCode = Integer.valueOf(status.toString());
if(statusCode == HttpStatus.NOT_FOUND.value()) {
return "error-404";
}
else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error-500";
}
}
return "error";
}
@Override
public String getErrorPath()
{
return "/error";
}
}
Это то, что я получил в терминале на клиенте:
2020-04-13 10:34:40.559 ERROR 12868 --- [nio-8081-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException$NotFound: 404 : [{"timestamp":"2020-04-13 10:34:40","status":404,"error":"Ticket not found with id: 1"}]] with root cause
И это переходит на страницу 500 ошибок вместо 404.
Я понимаю, почему это не работает. У меня нет ничего при обработке ошибки на стороне клиента, и она переходит к ошибке 500. Но я не знаю, что с этим делать.
ОБНОВЛЕНИЕ
Итак, я сделал это:
String url = "http://localhost:8080/api/ticket/";
try {
ResponseEntity<Ticket> ticket = restTemplate.getForEntity(url + id, Ticket.class);
model.addAttribute("ticket",ticket.getBody());
model.addAttribute("title","Tickets");
}catch (Exception e)
{
String msg = e.getMessage();
model.addAttribute("message",msg);
return "/error";
}
return "ticket";
И теперь, по крайней мере, я получаю страницу ошибки с реальным сообщением от бэкэнда. Но это решение работает вокруг MyErrorController. MyErrorController не запускается и в основном устарел.