GithubHelp home page GithubHelp logo

Comments (1)

NilsRenaud avatar NilsRenaud commented on May 27, 2024

Reproducer

Here is a reproducer (working on every platform):

import java.util.concurrent.CountDownLatch;

import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.http.HttpServerRequest;

public class Test2 {

  public static void main(String[] args) throws InterruptedException {
    HttpServerOptions options = new HttpServerOptions();
    options.setPort(8080);
    CountDownLatch latch = new CountDownLatch(1);
    Vertx.vertx()
         .createHttpServer(options)
         .requestHandler(Test2::handleRequest)
         .exceptionHandler(t -> t.printStackTrace())
         .listen()
         .onSuccess(a -> {
           System.out.println("SERVER : started.");
           latch.countDown();
         });
    latch.await();

    Vertx.vertx().createWebSocketClient().connect(8080, "localhost", "/")
         .onSuccess(ws -> {
           ws.exceptionHandler(t -> {
             System.out.println("CLIENT : Exception - " + t.getMessage());
             //t.printStackTrace();
           });
           ws.endHandler(__ -> System.out.println("CLIENT : WS ended:" + ws.closeStatusCode() + " " + ws.closeReason()));
           ws.writeTextMessage("message")
             .onSuccess(__ -> System.out.println("CLIENT : message sent"))
             .onFailure(t -> System.out.println("CLIENT : message error" + t.getMessage()));
         })
         .onFailure(t -> {
           System.out.println("CLIENT : failed to connect");
           t.printStackTrace();
         });
  }

  private static void handleRequest(HttpServerRequest req) {
    req.toWebSocket()
       .onSuccess(ws -> {
         System.out.println("SERVER : request received");
         ws.accept();
         ws.handler(b -> {
           System.out.println("SERVER : message received, close WS");
           ws.close(Short.parseShort("1004")); // Invalid status code
         });
       });
  }
}

It prints :

SERVER : started.
SERVER : request received
CLIENT : message sent
SERVER : message received, close WS
CLIENT : Exception - Invalid close frame getStatus code: 1004
CLIENT : Exception - Connection was closed
[vert.x-eventloop-thread-0] ERROR io.vertx.core.net.impl.ConnectionBase - Invalid close frame getStatus code: 1004

You can notice [vert.x-eventloop-thread-0] ERROR io.vertx.core.net.impl.ConnectionBase - Invalid close frame getStatus code: 1004 which is logged directly by Vert.x itself.
Moreover this exception already make its way to the WebSocket exception handler since we logged CLIENT : Exception - Invalid close frame getStatus code: 1004

Analysis

This boils down to this Http1xClientConnection.handleException method:

protected void handleException(Throwable e) {
    super.handleException(e); // ----- Call ConnectionBase#handleException which will log the exception since no handler is set.
    WebSocketImpl ws;
    LinkedHashSet<Stream> allStreams = new LinkedHashSet<>();
    synchronized (this) {
      ws = webSocket;
      allStreams.addAll(requests);
      allStreams.addAll(responses);
    }
    if (ws != null) {
      ws.handleException(e); // ----- Call the exception handler set in the WebSocket object.
    }
    for (Stream stream : allStreams) {
      stream.handleException(e);
    }
  }

Note: you can see that the exception handler is called twice. It looks invalid to me as an exception is a terminal state.
This double call to the exception handler comes from VertxHandler#exceptionCaught(...) which calls the connection exception handler and close the connection, which end in WebSocketImplBase#handleClose(...) calling its exception handler with HttpUtils.CONNECTION_CLOSED_EXCEPTION.

from vert.x.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.