This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit f2ce3f0e0182149f10aa55823a9860da7baa75b9
Author: Mark Thomas <[email protected]>
AuthorDate: Tue Oct 20 17:33:57 2026 +0100

    Improve error handling
    
    Co-authored by: Claude / Sonnet 5.5
---
 .../coyote/http11/upgrade/LocalStrings.properties  |  1 +
 .../http11/upgrade/UpgradeProcessorExternal.java   | 26 ++++++++++++++++++++++
 .../http11/upgrade/UpgradeServletInputStream.java  |  2 +-
 .../http11/upgrade/UpgradeServletOutputStream.java |  2 +-
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/coyote/http11/upgrade/LocalStrings.properties 
b/java/org/apache/coyote/http11/upgrade/LocalStrings.properties
index d2bfec972c..3a9aa98b4f 100644
--- a/java/org/apache/coyote/http11/upgrade/LocalStrings.properties
+++ b/java/org/apache/coyote/http11/upgrade/LocalStrings.properties
@@ -32,6 +32,7 @@ upgrade.sos.write.ise=It is illegal to call any of the 
write() methods in non-bl
 upgrade.sos.writeListener.null=It is illegal to pass null to setWriteListener()
 upgrade.sos.writeListener.set=It is illegal to call setWriteListener() more 
than once for the same upgraded connection
 
+upgradeProcessor.error=Error reported for upgraded connection
 upgradeProcessor.isCloseFail=Failed to close input stream associated with 
upgraded connection
 upgradeProcessor.osCloseFail=Failed to close output stream associated with 
upgraded connection
 upgradeProcessor.requiredClose=Closing upgraded connection due to 
closeRequired state of streams: Input [{0}], Output [{1}]
diff --git 
a/java/org/apache/coyote/http11/upgrade/UpgradeProcessorExternal.java 
b/java/org/apache/coyote/http11/upgrade/UpgradeProcessorExternal.java
index de89266965..b31913c0d0 100644
--- a/java/org/apache/coyote/http11/upgrade/UpgradeProcessorExternal.java
+++ b/java/org/apache/coyote/http11/upgrade/UpgradeProcessorExternal.java
@@ -53,6 +53,11 @@ public class UpgradeProcessorExternal extends 
UpgradeProcessorBase {
      */
     private final UpgradeInfo upgradeInfo;
 
+    /**
+     * The socket wrapper for the upgraded connection.
+     */
+    private final SocketWrapperBase<?> wrapper;
+
     /**
      * Constructs a new UpgradeProcessorExternal.
      *
@@ -63,6 +68,7 @@ public class UpgradeProcessorExternal extends 
UpgradeProcessorBase {
     public UpgradeProcessorExternal(SocketWrapperBase<?> wrapper, UpgradeToken 
upgradeToken,
             UpgradeGroupInfo upgradeGroupInfo) {
         super(upgradeToken);
+        this.wrapper = wrapper;
         this.upgradeInfo = new UpgradeInfo();
         if (upgradeGroupInfo != null) {
             upgradeInfo.setGroupInfo(upgradeGroupInfo);
@@ -142,6 +148,26 @@ public class UpgradeProcessorExternal extends 
UpgradeProcessorBase {
                 log.debug(sm.getString("upgradeProcessor.osCloseFail", ioe));
             }
             return SocketState.CLOSED;
+        } else if (status == SocketEvent.ERROR) {
+            // Give the listeners (if any) the chance to handle the error 
before
+            // the connection is closed.
+            Throwable error = wrapper.getError();
+            if (error == null) {
+                error = new 
IOException(sm.getString("upgradeProcessor.error"));
+            }
+            upgradeServletInputStream.onError(error);
+            upgradeServletOutputStream.onError(error);
+            try {
+                upgradeServletInputStream.close();
+            } catch (IOException ioe) {
+                log.debug(sm.getString("upgradeProcessor.isCloseFail", ioe));
+            }
+            try {
+                upgradeServletOutputStream.close();
+            } catch (IOException ioe) {
+                log.debug(sm.getString("upgradeProcessor.osCloseFail", ioe));
+            }
+            return SocketState.CLOSED;
         } else {
             // Unexpected state
             if (log.isDebugEnabled()) {
diff --git 
a/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java 
b/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java
index 80535d25d5..c44a692a64 100644
--- a/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java
+++ b/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java
@@ -296,7 +296,7 @@ public class UpgradeServletInputStream extends 
ServletInputStream {
     }
 
 
-    private void onError(Throwable t) {
+    final void onError(Throwable t) {
         if (listener == null || errorReported) {
             return;
         }
diff --git 
a/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java 
b/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java
index b1693f84a9..ca57656659 100644
--- a/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java
+++ b/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java
@@ -303,7 +303,7 @@ public class UpgradeServletOutputStream extends 
ServletOutputStream {
     }
 
 
-    private void onError(Throwable t) {
+    final void onError(Throwable t) {
         if (listener == null || errorReported) {
             return;
         }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to