【问题标题】:How to determine if an exception is a ClientAbortException如何确定异常是否为 ClientAbortException
【发布时间】:2017-06-24 23:05:52
【问题描述】:

因此,当用户取消对托管在 Tomcat 应用程序服务器上的 Web 应用程序的请求时,我会收到以下异常,并通过 Maven 处理依赖项管理:

ClientAbortException:  java.net.SocketException: Connection reset
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:406)
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
    at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:431)
    at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:419)
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91)
    ...

我有一个 Spring @ControllerAdvice 类,它处理所有异常并发送电子邮件。

@ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity defaultErrorHandler(final HttpServletRequest request, final Principal principal, final Exception e) {

    //send email with details of error

    return ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
}

但是,如果是ClientAbortException,我不想发送电子邮件。

我想做这样的事情:

if (!(e instanceof ClientAbortException)) {
    //send email with details of error
}

ClientAbortException 似乎不在我的类路径中,因为它是一个包含在 tomcat 服务器级库中的异常。

我可以检查e instance of SocketException,但我可能会错过我关心的其他SocketExceptions。我的下一个想法是这样的:

e instanceof SocketException && e.getMessage().contains("Connection reset")

但似乎应该有更直接的方法来做到这一点。

有什么想法吗?

【问题讨论】:

    标签: java spring maven tomcat exception-handling


    【解决方案1】:

    我查看 java 文档,ClientAbortException 是 IOException 的子级,因此您不能使用 SocketException 的实例。

    在我的 tomcat 版本中,引发异常的代码是:

    if (cnt > 0) {
            // real write to the adapter
            outputChunk.setBytes(buf, off, cnt);
            try {
                coyoteResponse.doWrite(outputChunk);
            } catch (IOException e) {
                // An IOException on a write is almost always due to
                // the remote client aborting the request.  Wrap this
                // so that it can be handled better by the error dispatcher.
                throw new ClientAbortException(e);
            }
        }
    

    我认为您只是为您的客户端中止异常创建一个新的异常处理程序。不要在不同的异常上使用实例。

    @ExceptionHandler(value = ClientAbortException.class)
    public ResponseEntity<ErrorResponse> handleClientAbort(Exception ex, HttpServletRequest req) {
        //YOUR HANDLER IMPLEMENTATION
    
    }
    

    您可以使用@Order 注解来配置precedence of exceptions

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 2015-11-14
      • 2017-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      相关资源
      最近更新 更多