ControllerAdvice не обрабатывает исключение, вызванное аспектом AfterThrowing
Эта проблема состоит из 3 слоев
- Сервис, который делает HTTP-вызовы
- Аспект, который консультирует службу выше, когда выдается исключение
- @ControllerAdvice Spring boot, который устанавливает код состояния перед возвратом результата клиенту
Чего я хочу добиться:
- Когда служба делает HTTP-вызов, который возвращает 404, я хочу обработать это с моим аспектом
- Мой аспект должен видеть, что служба получила 404, а затем выбрасывать пользовательское NotFoundException
- ControllerAdvice должен затем обработать это пользовательское исключение, возвращая код состояния 404 пользователю.
Вместо этого происходит то, что ControllerAdvice
пропускается, когда Aspect создает новое исключение NotFound, а клиент получает 500
вместо 404
,
Код выглядит примерно так:
обслуживание
@CatchHttpResult
public Map<String, Object> getUserInfo(String email) {
cpLocation.entering("getUserInfo");
String url = contactUrl+"/api/getContactInfo?id="+email;
HttpEntity<?> entity = new HttpEntity<>(headers);
ResponseEntity<Map> respEntity = restTemplate.exchange(url, HttpMethod.POST, entity,
Map.class);
return respEntity.getBody();
}
аспект
@Aspect
@Component
public class CatchHttpResultAspect {
@AfterThrowing(pointcut = "@annotation(CatchHttpResult)", throwing = "e")
public void httpAfterThrowing(JoinPoint joinPoint, Throwable e) throws Throwable {
if (e instanceof HttpClientErrorException) {
if (((HttpClientErrorException) e).getStatusCode() == HttpStatus.NOT_FOUND) {
throw new EntityNotFoundException("The requested entity was not found.");
}
}
throw e;
}
}
ControllerAdvice
@EnableWebMvc
@ControllerAdvice
public class ExceptionsController {
@ExceptionHandler(EntityNotFoundException.class)
protected ResponseEntity<Object> handleEntityNotFound(EntityNotFoundException ex) {
ApiError apiError = new ApiError(HttpStatus.NOT_FOUND);
apiError.setMessage(ex.getMessage());
return buildResponseEntity(apiError);
}
}
Я хочу, чтобы ControllerAdvice мог обрабатывать EntityNotFoundException, вместо этого этот код вообще не достигается.
Почему это происходит и как мне получить желаемое поведение?
Трассировки стека:
java.lang.reflect.UndeclaredThrowableException: null
at po.repository.service.MicroserviceIntercomm$$EnhancerBySpringCGLIB$$d580a067.getUserInfo(<generated>)
at po.repository.service.POService.getUserInfo(POService.java:523)
at po.repository.controller.RepositoryController.initiateData(RepositoryController.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
Спасибо:)