Skip to content

Commit 222a1c8

Browse files
committed
AsyncContext completion attempt after AsyncListener.onError is called #5675
Signed-off-by: Jorge Bescos Gascon <jorge.bescos.gascon@oracle.com>
1 parent ff5f5a8 commit 222a1c8

2 files changed

Lines changed: 83 additions & 5 deletions

File tree

core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,14 @@ public void run() {
277277
}
278278
}
279279

280+
static boolean isIOException(Throwable t) {
281+
boolean ioException = false;
282+
while (t != null && !(ioException = t instanceof IOException)) {
283+
t = t.getCause();
284+
}
285+
return ioException;
286+
}
287+
280288
/**
281289
* Get the Jersey server runtime background scheduler.
282290
*
@@ -669,11 +677,18 @@ public OutputStream getOutputStream(final int contentLength) throws IOException
669677

670678
} catch (final Throwable ex) {
671679
if (response.isCommitted()) {
672-
/**
673-
* We're done with processing here. There's nothing we can do about the exception so
674-
* let's just log it.
675-
*/
676-
LOGGER.log(Level.SEVERE, LocalizationMessages.ERROR_WRITING_RESPONSE_ENTITY(), ex);
680+
if (isIOException(ex)) {
681+
skipFinally = true;
682+
LOGGER.log(Level.WARNING, "Response was sent, but there is IO issue", ex);
683+
// Connection is broken. Re-throw to the web container to remove the connection.
684+
throw new MappableException("Response was sent, but there is IO issue", ex);
685+
} else {
686+
/**
687+
* We're done with processing here. There's nothing we can do about the exception so
688+
* let's just log it.
689+
*/
690+
LOGGER.log(Level.SEVERE, LocalizationMessages.ERROR_WRITING_RESPONSE_ENTITY(), ex);
691+
}
677692
} else {
678693
skipFinally = true;
679694
if (ex instanceof RuntimeException) {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.server;
18+
19+
import static org.junit.jupiter.api.Assertions.assertFalse;
20+
import static org.junit.jupiter.api.Assertions.assertTrue;
21+
22+
import java.io.IOException;
23+
import java.io.UncheckedIOException;
24+
import java.net.SocketException;
25+
26+
import org.junit.jupiter.api.Test;
27+
28+
public class ServerRuntimeTest {
29+
30+
@Test
31+
public void ioExceptionInRoot() {
32+
assertTrue(ServerRuntime.isIOException(new IOException()));
33+
assertTrue(ServerRuntime.isIOException(new IOException(new RuntimeException())));
34+
}
35+
36+
@Test
37+
public void ioExceptionInCause() {
38+
assertTrue(ServerRuntime.isIOException(new RuntimeException(new IOException())));
39+
assertTrue(ServerRuntime.isIOException(new RuntimeException(new RuntimeException(new IOException()))));
40+
}
41+
42+
@Test
43+
public void unckeckedIOExceptionInCause() {
44+
assertTrue(ServerRuntime.isIOException(new UncheckedIOException(new SocketException())));
45+
assertTrue(ServerRuntime.isIOException(new RuntimeException(new UncheckedIOException(new SocketException()))));
46+
}
47+
48+
@Test
49+
public void noIOException() {
50+
assertFalse(ServerRuntime.isIOException(new RuntimeException()));
51+
assertFalse(ServerRuntime.isIOException(new RuntimeException(new RuntimeException())));
52+
}
53+
54+
@Test
55+
public void nullException() {
56+
assertFalse(ServerRuntime.isIOException(null));
57+
}
58+
59+
@Test
60+
public void nullCause() {
61+
assertFalse(ServerRuntime.isIOException(new RuntimeException((Throwable) null)));
62+
}
63+
}

0 commit comments

Comments
 (0)