Исключение ResponseStatusException(404) приводит к статусу ответа 401 (с «Сбой в @ExceptionHandler»)

#spring #spring-boot #exception

#spring #загрузка пружины #исключение

Вопрос:

У меня есть этот код в службе

 val user = userRepo.findById(id).orElseThrow { UsernameNotFoundException("User with id $id was not found.") }
 

и в контроллере

 @ExceptionHandler
    fun handleUsernameNotFoundException(e: UsernameNotFoundException) {
        throw ResponseStatusException(HttpStatus.NOT_FOUND, e.localizedMessage)
    }
@PreAuthorize("somecheck('PUT user/{id}') || othercheck(#id)")
@PutMapping("/{id}")
fun update(@PathVariable id: UUID, @RequestBody @Valid data: Data) =
    service.update(id, data)
 

Если я помещаю точку останова внутри обработчика или службы (или что-то в системе), оно явно выполняется. Несмотря на это, ответ 401 неавторизован. Очевидно, что запрос авторизован, потому что, если я передам правильный UUID, я смогу обновить данные.

Между тем в журналах:

 2020-12-16 12:54:43.751  WARN 16396 --- [io-8080-exec-10] .m.m.a.ExceptionHandlerExceptionResolver : Failure in @ExceptionHandler com.heilatech.customerportal.user.api.UserController#handleUsernameNotFoundException(UsernameNotFoundException)

org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND "User with id 53b522db-857a-4535-bddb-d1da3f3eeea4 was not found."
    at ...UserController.handleUsernameNotFoundException(UserController.kt:31) ~[classes/:na]
    at ....UserController$FastClassBySpringCGLIB$2f4c321e.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:687) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at ....UserController$EnhancerBySpringCGLIB$c2918f47.handleUsernameNotFoundException(<generated>) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:407) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:61) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:141) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:80) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1300) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1111) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:920) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.39.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.39.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 

Ответ №1:

Я понял! Похоже, что вы не можете создать другое исключение внутри ExceptionHandler. Правильный способ

 @ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(UsernameNotFoundException::class)
fun handleUsernameNotFoundException() {
    // nothing to do
}