에러 발생: 클라이언트 메시지 처리 중 예외 발생.
handleClientMessageProcessingError 호출: 스프링이 StompSubProtocolErrorHandler의 해당 메서드를 호출하며, 처리 실패한 원본 메시지(clientMessage)와 발생한 예외(Throwable)를 인자로 넘겨줍니다.
ERROR 프레임 생성 시작: 이 메서드 내부에서 StompHeaderAccessor.create(StompCommand.ERROR)를 호출하여 클라이언트에게 보낼 ERROR 메시지의 헤더를 만들기 시작합니다.
에러 정보 추가: 생성된 accessor를 사용해 에러에 대한 상세 정보를 헤더에 추가합니다.
accessor.setMessage("Error processing message: " + ex.getMessage());
필요하다면 accessor.setDetailedMessage(...)나 커스텀 헤더(accessor.setHeader("custom-error-code", "1234"))를 추가할 수 있습니다.
에러 발생 (서버): 클라이언트가 잘못된 요청(예: 권한 없는 토픽 구독, 잘못된 헤더)을 보내거나 서버 내부에서 문제가 발생합니다.
ERROR 프레임 전송 (서버 → 클라이언트): 서버는 에러의 원인을 담은 ERROR 프레임을 클라이언트로 전송합니다.
연결 종료 (서버): STOMP 프로토콜 규칙에 따라, 서버는 ERROR 프레임을 보낸 후 해당 클라이언트와의 WebSocket/TCP 연결을 닫습니다.
onStompError 콜백 실행 (클라이언트): stomp.js는 수신한 ERROR 프레임을 처리하기 위해 onStompError 함수를 호출합니다. 이 함수에서 개발자는 에러 로그를 남기거나 사용자에게 알림을 표시할 수 있습니다.
연결 종료 감지 (클라이언트): 서버가 연결을 끊었으므로, 클라이언트의 WebSocket은 연결 종료(close) 이벤트를 감지합니다. stomp.js에서는 이 시점에 onWebSocketClose 콜백이 트리거됩니다.
결론적으로 onStompError가 실행되는 시점에는 이미 연결이 곧 끊어지거나 끊어진 상태인 것이 맞습니다. onStompError 콜백은 연결 종료를 막기 위한 것이 아니라, 종료되기 직전 왜 에러가 발생했는지 파악하고 후속 조치(로깅, UI 처리 등)를 하기 위해 존재합니다.
ERROR 발생 시 연결이 끊기는 것은 프로토콜의 표준 동작이므로, 이를 막으려고 하기보다는 연결이 끊어진 후의 상황에 대처하는 방식으로 코드를 작성해야 합니다.
cf. reconnectDelay 옵션을 사용하면 ERROR로 인해 연결이 종료되더라도 stomp.js가 자동으로 재연결을 시도하게 만들어 서비스의 안정성을 높일 수 있습니다.