Dan
Dan

Reputation: 10538

ExecutorService runnable never hits try when an Exception occurs

I am trying to use a CompletableFuture<T> to respond to a LWJGL OpenGL context being created. This is done by calling the open method on LWJGLGameWindow. Here is the concerning code:

  @Override
  public CompletableFuture<?> open() {
    CompletableFuture<Void> future = new CompletableFuture<>();

    scheduledExecutorService.schedule(() -> {
      future.completeExceptionally(new TimeoutException("Could not establish contact with LWJGL"));
    }, 2000, TimeUnit.MILLISECONDS);

    scheduledExecutorService.execute(() -> {
      try {
        display.setDisplayMode(new DisplayMode(defaultWidth, defaultHeight));
        display.create();
        future.complete(null);
      } catch (LWJGLException e) {
        future.completeExceptionally(e);
      }
    });
    return future;
  }

The idea is to defer the creation of a display on a scheduled executor service. This is set up to be a single threaded scheduled executor service, because OpenGL contexts are thread-bound. If it takes too long to connect to LWJGL, then the returned future will break out of itself early.

The problem is that in unit tests, this works absolutely swimmingly. However, when I try and debug the program, any call to any of the display methods results in a real exception being thrown by lwjgl (because my library for lwjgl is not linked. This is still thrown as a LwjglException, though). For some reason, this exception is not picked up from the try-catch in this code here, and instead the exception is swallowed; the future never gets completed exceptionally.

So somewhere along the line, my exception is being swallowed in this code.

NB: display is simply a interface around LWJGL's Display - no fancy magic going on there. scheduledExecutorService is a single threaded scheduled executor.

I also appreciate that .submit() and schedule on scheduledExecutorService both return Future<T> but this lacks the composition I would like to use from CompletableFuture<T>. I'd like to be able to keep using that if at all possible.

Upvotes: 2

Views: 128

Answers (1)

Dan
Dan

Reputation: 10538

The code actually works exactly as it should. The real problem is that the error I was expecting, java.lang.UnsatisifiedLinkError, is not an Exception but actually an Error. Amending the code to catch a Throwable solves this issue.

Upvotes: 1

Related Questions