https://bz.apache.org/bugzilla/show_bug.cgi?id=69920

            Bug ID: 69920
           Summary: WsRemoteEndpointImplBase breaks contracts when session
                    is closed
           Product: Tomcat 11
           Version: 11.0.14
          Hardware: PC
            Status: NEW
          Severity: normal
          Priority: P2
         Component: WebSocket
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: -------

(I already reported similar 67293, in current issue I focus strictly on code
correctness, because correctness is binary - correct or incorrect)

WsRemoteEndpointImplBase throws 7 times exception caused by
sm.getString("wsRemoteEndpoint.closed*

6 times it is IllegalStateException, one IOException

IMHO correct variant is IOException. Let inspect case by case
IllegalStateException

1. WsRemoteEndpointImplBase.WsOutputStream#flush: java.io.OutputStream#flush
javadoc declares IOException as problem indicatior. Not illegal state exception


2. WsRemoteEndpointImplBase.WsOutputStream#write(byte[], int, int):
3. WsRemoteEndpointImplBase.WsOutputStream#write(int):
java.io.OutputStream#write is more precise in javadoc:
Throws:
IOException – if an I/O error occurs. In particular, an IOException may be
thrown if the output stream has been closed.


4. WsRemoteEndpointImplBase.WsWriter#write:
5. WsRemoteEndpointImplBase.WsWriter#flush: java.io.Writer javadoc states:
While the stream is open, the append(char), append(CharSequence),
append(CharSequence, int, int), flush(), write(int), write(char[]), and
write(char[], int, int) methods do nothing. After the stream has been closed,
these methods all throw IOException.

6. WsRemoteEndpointImplBase#writeMessagePart: this is private class without
contract, however raising IllegalStateException breaks contract of
jakarta.websocket.RemoteEndpoint.Basic#sendText(java.lang.String, boolean) :
Throws:
IllegalArgumentException – if fragment is null.

Here is example that illegal argument exception is thrown when session is
closed

java.lang.IllegalStateException: Message will not be sent because the WebSocket
session has been closed
        at
org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:458)
        at
org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlockInternal(WsRemoteEndpointImplBase.java:316)
        at
org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:269)
        at
org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:253)
        at
org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPartialString(WsRemoteEndpointImplBase.java:226)
        at
org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:48)

Conclusion: when session is closed, IOException should be consistently thrown,
otherwise java.io contract is broken explicit or by deduction and - in one case
- jakarta.websocket contract is broken

Incorrect implementation confuses developers. Exception handling cannot trust
contract and needs inspection implementation details.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to