title: How to properly report an error to client through WebSockets
body: <p>How do I properly close a websocket and and provide a clean, informative response to the client when an internal error occurs on my server? In my current case, the client must provide a parameter when it connects, and I am trying to handle incorrect or missing parameters received by OnOpen.</p>
  
  <p><a href="https://github.com/MartinanderssonDotcom/websocket-exception-handling/blob/master/src/main/java/martinandersson/com/websockets/MyServerEndpoint.java" rel="noreferrer" title="MyServerEndpoint.java">This example</a> suggests I can just throw an exception in OnOpen, which will ultimately call OnError where I can close with a reason and message. It kinda works, but the client only receives an EOF, 1006, CLOSE_ABNORMAL. </p>
  
  <p>Also, because I have found no other discussion, I can't tell what might be best practice.</p>
  
  <p>I'm using the JSR-356 spec, as follows:</p>
  
  <pre><code>@ClientEndpoint
  @ServerEndpoint(value="/ws/events/")
  public class WebSocketEvents
  {
      private javax.websocket.Session session;
      private long token;
  
      @OnOpen
      public void onWebSocketConnect(javax.websocket.Session session) throws BadRequestException
      {
          logger.info("WebSocket connection attempt: " + session);
          this.session = session;
          // this throws BadRequestException if null or invalid long
          // with short detail message, e.g., "Missing parameter: token"
          token = HTTP.getRequiredLongParameter(session, "token");
      }
  
      @OnMessage
      public void onWebSocketText(String message)
      {
          logger.info("Received text message: " + message);
      }
  
      @OnClose
      public void onWebSocketClose(CloseReason reason)
      {
          logger.info("WebSocket Closed: " + reason);
      }
  
      @OnError
      public void onWebSocketError(Throwable t)
      {
          logger.info("WebSocket Error: ");
  
          logger.debug(t, t);
          if (!session.isOpen())
          {
              logger.info("Throwable in closed websocket:" + t, t);
              return;
          }
  
          CloseCode reason = t instanceof BadRequestException ? CloseReason.CloseCodes.PROTOCOL_ERROR : CloseReason.CloseCodes.UNEXPECTED_CONDITION;
          try
          {
              session.close(new CloseReason(reason, t.getMessage()));
          }
          catch (IOException e)
          {
              logger.warn(e, e);
          }
  
      }
  }
  </code></pre>
  
  <p><strong>Edit:</strong> The exception throwing per linked example seems weird, so now I am catching exception within OnOpen and immediately doing </p>
  
  <pre><code>session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "some text")); 
  </code></pre>
  
  <p><strong>Edit:</strong> This turned out to be correct, though a separate bug disguised it for a while.</p>
  
  <hr>
  
  <p><strong>Edit2</strong>: Clarification: <code>HTTP</code> is my own static utility class. <code>HTTP.getRequiredLongParameter()</code> gets query parameters from the client's initial request by using</p>
  
  <pre><code>session.getRequestParameterMap().get(name)
  </code></pre>
  
  <p>and does further processing.</p>