2017-02-07 6 views
0

Так я получаю следующее исключение, когда пользователь отменяет запрос на моем веб-приложение, размещенное на сервере приложений Tomcat, с управлением зависимостей обрабатываются с помощью Maven:Как определить, если исключение является ClientAbortException

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) 
    ... 

I имеют класс 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 не кажется, что на моем пути к классам, как это исключение включено в Lib сервер Tomcat уровня.

Я мог проверить, e instance of SocketException, но я мог бы пропустить другие SocketException s, которые меня волнуют. Моя следующая идея была примерно такой:

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

Но, похоже, должен быть более простой способ сделать это.

Любые идеи?

ответ

0

Я смотрю на java doc, а ClientAbortException является дочерним элементом IOException, поэтому вы не можете использовать экземпляр для SocketException.

На моей версии кота кода, который бросает исключение составляет:

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.