@Test public void do_not_fail_nor_log_not_attempt_to_send_error_if_ClientAbortException_is_raised() throws Exception { system.pluginStreamException = new ClientAbortException("Simulating ClientAbortException"); when(pluginRepository.hasPlugin("myplugin")).thenReturn(true); Response response = call("/static/myplugin/foo.css"); assertThat(response.code()).isEqualTo(200); assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty(); assertThat(logTester.logs(LoggerLevel.TRACE)).contains( "Client canceled loading resource [static/foo.css] from plugin [myplugin]: org.apache.catalina.connector.ClientAbortException: Simulating ClientAbortException"); }
private static WebService newClientAbortWs() { return newWs("api/foo", a -> a.setHandler((req, resp) -> { throw new ClientAbortException(); })); }
// If we really have something to write 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); } }
/** * Sends the buffer data to the client output, checking the * state of Response and calling the right interceptors. * * @param buf the ByteBuffer to be written to the response * * @throws IOException An underlying IOException occurred */ public void realWriteBytes(ByteBuffer buf) throws IOException { if (closed) { return; } if (coyoteResponse == null) { return; } // If we really have something to write if (buf.remaining() > 0) { // real write to the adapter try { coyoteResponse.doWrite(buf); } 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); } } }
/** * Sends the buffer data to the client output, checking the * state of Response and calling the right interceptors. * * @param buf the ByteBuffer to be written to the response * * @throws IOException An underlying IOException occurred */ public void realWriteBytes(ByteBuffer buf) throws IOException { if (closed) { return; } if (coyoteResponse == null) { return; } // If we really have something to write if (buf.remaining() > 0) { // real write to the adapter try { coyoteResponse.doWrite(buf); } 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); } } }
throw new ClientAbortException(e);
throw new ClientAbortException(e);
/** * Sends the buffer data to the client output, checking the * state of Response and calling the right interceptors. * * @param buf Byte buffer to be written to the response * @param off Offset * @param cnt Length * * @throws IOException An underlying IOException occurred */ public void realWriteBytes(byte buf[], int off, int cnt) throws IOException { if (closed) return; if (coyoteResponse == null) return; // If we really have something to write 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); } } }
/** * Sends the buffer data to the client output, checking the * state of Response and calling the right interceptors. * * @param buf Byte buffer to be written to the response * @param off Offset * @param cnt Length * * @throws IOException An underlying IOException occurred */ public void realWriteBytes(byte buf[], int off, int cnt) throws IOException { if (closed) return; if (coyoteResponse == null) return; // If we really have something to write 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); } } }
/** * Sends the buffer data to the client output, checking the * state of Response and calling the right interceptors. * * @param buf Byte buffer to be written to the response * @param off Offset * @param cnt Length * * @throws IOException An underlying IOException occurred */ public void realWriteBytes(byte buf[], int off, int cnt) throws IOException { if (closed) return; if (coyoteResponse == null) return; // If we really have something to write 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); } } }
throw new ClientAbortException(e);
throw new ClientAbortException(coyoteResponse.getErrorException());
throw new ClientAbortException(coyoteResponse.getErrorException());
/** * Flush bytes or chars contained in the buffer. * * @throws IOException An underlying IOException occurred */ protected void doFlush(boolean realFlush) throws IOException { if (suspended) return; doFlush = true; if (initial) { coyoteResponse.sendHeaders(); initial = false; } if (bb.getLength() > 0) { bb.flushBuffer(); } doFlush = false; if (realFlush) { coyoteResponse.action(ActionCode.CLIENT_FLUSH, coyoteResponse); // If some exception occurred earlier, or if some IOE occurred // here, notify the servlet with an IOE if (coyoteResponse.isExceptionPresent()) { throw new ClientAbortException (coyoteResponse.getErrorException()); } } }