StompSubProtocolErrorHandler

임기준·2025년 7월 22일
0

What

  • 서버에서 클라이언트가 보낸 메시지를 처리하다가 예외(Exception)가 발생하면, StompSubProtocolErrorHandler가 이 예외를 가로챕니다. 이때 핸들러의 주된 임무는 "클라이언트님, 당신이 보낸 메시지 처리 중에 이런 문제가 발생했습니다" 라고 알려주는 것입니다.

How

  • StompSubProtocolErrorHandler의 처리 흐름은 다음과 같습니다.
  1. 에러 발생: 클라이언트 메시지 처리 중 예외 발생.

  2. handleClientMessageProcessingError 호출: 스프링이 StompSubProtocolErrorHandler의 해당 메서드를 호출하며, 처리 실패한 원본 메시지(clientMessage)와 발생한 예외(Throwable)를 인자로 넘겨줍니다.

  3. ERROR 프레임 생성 시작: 이 메서드 내부에서 StompHeaderAccessor.create(StompCommand.ERROR)를 호출하여 클라이언트에게 보낼 ERROR 메시지의 헤더를 만들기 시작합니다.

  4. 에러 정보 추가: 생성된 accessor를 사용해 에러에 대한 상세 정보를 헤더에 추가합니다.

  • accessor.setMessage("Error processing message: " + ex.getMessage());

  • 필요하다면 accessor.setDetailedMessage(...)나 커스텀 헤더(accessor.setHeader("custom-error-code", "1234"))를 추가할 수 있습니다.

  1. 최종 에러 메시지 반환: 설정된 헤더와 에러 메시지 본문을 담은 완전한 Message<byte[]> 객체를 생성하여 반환합니다. 이 반환된 메시지가 WebSocket을 통해 클라이언트에게 전송됩니다.

Tip

  • StompSubProtocolErrorHandler 는 기본구현체로 기본적으로 어떻게 처리하는지 정의되어 있고, 우리가 에러를 커스터마이징할 때 해당 클래스를 override 하면 된다.

일반적인 에러의 흐름 (ex.stompjs)

  1. 에러 발생 (서버): 클라이언트가 잘못된 요청(예: 권한 없는 토픽 구독, 잘못된 헤더)을 보내거나 서버 내부에서 문제가 발생합니다.

  2. ERROR 프레임 전송 (서버 → 클라이언트): 서버는 에러의 원인을 담은 ERROR 프레임을 클라이언트로 전송합니다.

  3. 연결 종료 (서버): STOMP 프로토콜 규칙에 따라, 서버는 ERROR 프레임을 보낸 후 해당 클라이언트와의 WebSocket/TCP 연결을 닫습니다.

  4. onStompError 콜백 실행 (클라이언트): stomp.js는 수신한 ERROR 프레임을 처리하기 위해 onStompError 함수를 호출합니다. 이 함수에서 개발자는 에러 로그를 남기거나 사용자에게 알림을 표시할 수 있습니다.

  5. 연결 종료 감지 (클라이언트): 서버가 연결을 끊었으므로, 클라이언트의 WebSocket은 연결 종료(close) 이벤트를 감지합니다. stomp.js에서는 이 시점에 onWebSocketClose 콜백이 트리거됩니다.

결론적으로 onStompError가 실행되는 시점에는 이미 연결이 곧 끊어지거나 끊어진 상태인 것이 맞습니다. onStompError 콜백은 연결 종료를 막기 위한 것이 아니라, 종료되기 직전 왜 에러가 발생했는지 파악하고 후속 조치(로깅, UI 처리 등)를 하기 위해 존재합니다.

Keypoint

ERROR 발생 시 연결이 끊기는 것은 프로토콜의 표준 동작이므로, 이를 막으려고 하기보다는 연결이 끊어진 후의 상황에 대처하는 방식으로 코드를 작성해야 합니다.

cf. reconnectDelay 옵션을 사용하면 ERROR로 인해 연결이 종료되더라도 stomp.js가 자동으로 재연결을 시도하게 만들어 서비스의 안정성을 높일 수 있습니다.

연결을 종료하지 않고 에러처리 하는 방법

ex. 인증토큰의 만료 처리

  • 컨셉 : ERROR 로 처리하지 말고 MESSAGE 로 처리해라.
  • StompSubProtocolErrorHandler 에서 에러메세지를 받아서 토큰 갱신에 대한 요청을 사용자에게 메세지를 전송하게 한다.
  • 단, CONNECT 에서 오류 발생시 그냥 오류를 던져서 클라이언트 onStompError 에서 토큰 갱신 후 client.active() 를 시도한다.
profile
openerzone

0개의 댓글