In some application setups, the WebSocket server does not transmit the disconnect message to the client, so that the client has no idea that the established connection has been terminated.

This issue arises when the application uses SimpleBrokerMessageHandler and the error handler is set to the instance of StompSubProtocolErrorHandler or an extended class that does not override the handleErrorMessageToClient method.

The commit fixes disconnect message population so that java.lang.IllegalArgumentException: No StompHeaderAccessor exception is not thrown in the handleErrorMessageToClient method in StompSubProtocolErrorHandler class.

A reproducible example for the case is available here: - https://github.com/alexjansons/spring-sandbox/blob/main/web-socket/disconnect-error/src/main/java/com/example/websocket/disconnecterror/Application.java - https://github.com/alexjansons/spring-sandbox/blob/main/web-socket/disconnect-error/src/test/java/com/example/websocket/disconnecterror/ApplicationTests.java

The issue arises when the client fails to send heartbeats for specific period, causing the server to terminate the session by invoking the handleDisconnect method in the SimpleBrokerMessageHandler.HeartbeatTask class. This issue was discovered in spring-websocket-5.3.13 but still persists in the latest code base.

If the error handler is not set, then there is no problem as the message is delivered to the client in this scenario. A reproducible example that illustrates this is the DisconnectWithoutErrorHandler.test found at https://github.com/alexjansons/spring-sandbox/blob/main/web-socket/disconnect-error/src/test/java/com/example/websocket/disconnecterror/ApplicationTests.java#L97.

However if the error handler is set to StompSubProtocolErrorHandler class instance or the instance of extended class given that the latter does not implement it's own handleErrorMessageToClient method, the disconnect message transmission process faces the IllegalArgumentException exception in the aforementioned method. The exception is caught and then silently ignored in SubProtocolWebSocketHandler.handleMessage method, which results in no message being sent to the client. This case is covered in DisconnectWithErrorHandler.test at https://github.com/alexjansons/spring-sandbox/blob/main/web-socket/disconnect-error/src/test/java/com/example/websocket/disconnecterror/ApplicationTests.java#L83.

A workaround for this issue is to extend the StompSubProtocolErrorHandler class for the error handler and re-implement the method handleErrorMessageToClient so that it does not generate an exception. An example of this workaround can be found at https://github.com/alexjansons/spring-sandbox/blob/main/web-socket/disconnect-error/src/main/java/com/example/websocket/disconnecterror/Application.java#L24.