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]