【问题标题】:GlobalExceptionHandler always returns 500GlobalExceptionHandler 总是返回 500
【发布时间】:2019-10-28 09:09:18
【问题描述】:

我有以下异常处理程序:

@Log4j2
@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(Exception.class)
public ResponseEntity handleException(Exception e) {
    logExceptionWithPath("Unhandled general exception", e);
    return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}

@ResponseBody
@ExceptionHandler({ValidationException.class})
public ResponseEntity<ErrorResponse> handleBindException(ValidationException ex) {
    logExceptionWithPath("Validation exception", ex);
    return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);
}


@ResponseBody
@ExceptionHandler({BindException.class})
public ResponseEntity<ErrorResponse> handleBindException(BindException ex) {
    logExceptionWithPath("Bind exception", ex);
    return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);
}

@ResponseBody
@ExceptionHandler(AmbiguousTermException.class)
public ResponseEntity<ErrorResponse> handleAmbiguousTermException(AmbiguousTermException ex) {
    logExceptionWithPath("AmbiguousTermException", ex);
    return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);
}

此代码应包装异常并返回带有正确状态代码的 ResponseEntity。

但相反,我总是得到这个:

{
"timestamp": 1560445348350,
"status": 500,
"error": "Internal Server Error",
"message": "I/O error on POST request for \"******": Error code:400 Message: ; nested exception is java.io.IOException: Error code:400 Message: ",
"path": "*****"
}

在日志中,我总是有 logExceptionWithPath 产生的消息,所以看起来 ExceptionHandler 工作正常,但是某处有 IOException。

每个异常(以及每个@ExceptionHandler)的响应都是相似的

以下是我的应用和 spring 的几条日志:

2019-06-13 17:26:00,237 DEBUG *:102 - assertTermsUnequivocal
2019-06-13 17:26:00,237 DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver:403 - Using @ExceptionHandler public org.springframework.http.ResponseEntity<*.ErrorResponse> *.GlobalExceptionHandler.handleAmbiguousTermException(*.AmbiguousTermException)
2019-06-13 17:26:00,238 ERROR *.GlobalExceptionHandler:92 - AmbiguousTermException for path: http://*/search
here stack trace from AmbiguousTermException
2019-06-13 17:26:00,239 DEBUG org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor:268 - Using 'application/json', given [text/plain, application/json, application/cbor, application/*+json, */*] and supported [application/json, application/*+json, application/json, application/*+json, application/cbor]
2019-06-13 17:26:00,239 DEBUG org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor:90 - Writing [*.ErrorResponse@17bd7832]
2019-06-13 17:26:00,240 DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver:143 - Resolved [*.AmbiguousTermException: terms are ambiguous]
2019-06-13 17:26:00,240 DEBUG org.springframework.web.servlet.DispatcherServlet:1130 - Completed 400 BAD_REQUEST

这些都来自有趣的日志。也许这根本没有连接到 Spring,而是它正在运行的服务器? 无论如何,如果您有任何线索为什么它不起作用,请留下答案或评论。

【问题讨论】:

    标签: java spring spring-boot exception


    【解决方案1】:

    您必须将响应状态添加到 @ResponseStatus(HttpStatus.NOT_FOUND) 等方法中

    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST) // Added this annotation
    @ExceptionHandler(AmbiguousTermException.class)
    public ResponseEntity<ErrorResponse> handleAmbiguousTermException(AmbiguousTermException ex) {
        logExceptionWithPath("AmbiguousTermException", ex);
        return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST);
    }
    

    【讨论】:

      【解决方案2】:

      仅当上述解决方案不起作用时。如果您已经检查了 GlobalExceptionHandler 并且一切正常。

      就我而言,其他异常情况一切正常。 对于要返回错误请求状态的不同异常,我有一个处理程序方法。所有异常都按预期运行,除了一个。

      恰好这个奇怪的异常被扩展为Exception,处理Exception返回错误500。

      为了解决这个问题,我只是将其扩展为 RuntimeException 而不是 Exception,因为我的 RuntimeException 被配置为返回错误的请求状态。

      为清楚起见,请看下面的示例:

      GlobalExceptionHandler .java

      @RestControllerAdvice
      public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
      
          ...
      
          @ExceptionHandler(Exception.class)
          public final ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex, HttpServletRequest request) {
              printErrorLogs(ex, request, HttpStatus.INTERNAL_SERVER_ERROR);
              return getErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, ex);
          }
      
          @ExceptionHandler({CustomException1.class, CustomException2.class, CustomException3.class})
          public final ResponseEntity<ErrorResponse> handleCustomRuntimeException(RuntimeException ex, HttpServletRequest request) {
              printErrorLogs(ex, request, HttpStatus.BAD_REQUEST);
              return processErrorResponse(ex.getMessage());
          }
      
          ...
      
      }
      

      CustomException1.java

      public class CustomException1 extends RuntimeException {
          private static final long serialVersionUID = 1L;
      
          public CustomException1 () {
              super();
          }
      
          public CustomException1 (String message) {
              super(message);
          }
      
          public CustomException1 (String message, Throwable cause) {
              super(message, cause);
          }
      
          public CustomException1 (Throwable cause) {
              super(cause);
          }
      
          protected CustomException1 (String message, Throwable cause, boolean enableSuppression, boolean
                  writableStackTrace) {
              super(message, cause, enableSuppression, writableStackTrace);
          }
      }
      

      我只是将自定义异常父级从 Exception 更改为 RuntimeException

      就我而言,我知道我的GlobalExceptionHandler 正在工作,除了特定的例外情况。经过检查,这个有问题的自定义异常是从 Exception 扩展而来的,它已经有一个返回错误 500 的处理程序。为了处理错误并返回错误的请求状态,我将把它扩展到 RuntimeException,因为我处理了这个异常返回错误的请求状态。

      同样,此解决方案仅适用于这种情况。您只需要检查您要检查/处理/自定义处理的异常的异常处理程序。

      回到你的问题,没有显示 AmbigousTermException 是如何定义的。我认为它的父级是Exception,并且您有一个返回错误 500 的异常处理程序。

      这就是为什么您总是得到错误 500 状态的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-28
        • 2020-04-20
        • 1970-01-01
        • 1970-01-01
        • 2014-11-30
        • 2016-05-19
        • 2015-03-10
        • 1970-01-01
        相关资源
        最近更新 更多