jooby-project / jooby

The modular web framework for Java and Kotlin
https://jooby.io
Apache License 2.0
1.7k stars 199 forks source link

reactive: Reactive types must support side-effect handlers #3486

Closed hidemikimura closed 1 month ago

hidemikimura commented 1 month ago

It seems that something is being sent after the response is sent with Context.send() in CompletionStage. Can the process here in io.jooby.internal.handler.apply() be changed?

      } else if (result instanceof CompletionStage future) {
        future.whenComplete(
            (value, x) -> {
              // Add the following if statement
              if (ctx.isResponseStarted()) {
                return;
              }
              try {
                Route.After after = ctx.getRoute().getAfter();
                if (after != null) {
                  // run after:
                  after.apply(ctx, value, unwrap((Throwable) x));
                }
                if (x != null) {
                  Throwable exception = unwrap((Throwable) x);
                  ctx.sendError(exception);
                } else {
                  ctx.render(value);
                }
              } catch (Throwable cause) {
                ctx.sendError(cause);
              }
            });
        // Return context to mark as handled
        return ctx;
      }
jknack commented 1 month ago

Hi, don't follow. what would you like to change?

hidemikimura commented 1 month ago

Executing Context.send() within CompletionStage will raise an exception after the response. Please make sure that no exception is raised.

jknack commented 1 month ago

Please add an example to reproduce the issue.

hidemikimura commented 1 month ago
install(new NettyServer());
setExecutionMode(ExecutionMode.EVENT_LOOP);
use(ReactiveSupport.concurrent());

get("/", ctx -> CompletableFuture.supplyAsync(() -> {
    ctx.send("top page");
    return ctx;
}));
hidemikimura commented 1 month ago

Thanks for the correction