elysia icon indicating copy to clipboard operation
elysia copied to clipboard

afterHandle not running with @elysiajs/html plugin on autoDetect

Open bojkomatias opened this issue 2 years ago • 7 comments

Hi, loving the project @SaltyAom <3 much love from Argentina

I'm having this issue with afterHandle not executing in certain cases.

const app = new Elysia()
  .onAfterHandle(() => console.log("GLOBAL AFTER HANDLE"))
  .use(html())
  .onAfterHandle(() => console.log("GLOBAL AFTER HANDLE, AFTER HTML PLUGIN"))
  .get(
    "/hello",
    () => {
      console.log("HANDLER");
      return "hi";
    },
    { afterHandle: () => console.log("LOCAL AFTER HANDLE") },
  )

The code above wont run the local afterHandle and won't run the global one the after plugin. But here's the catch, if I configure: .use(html({ autoDetect: false })) It executes all just fine.

So my guess is the issue has to do with the autoDetecting part of the plugin. Maybe the onAfterHandle is early returing, and this avoids the rest from being called.

This is happening to me with:

    "elysia": "0.7.16",
    "@elysiajs/html": "^0.7.3",
    "@kitajs/html": "^3.0.2",
    "@kitajs/ts-html-plugin": "^1.3.0"

I will keep trying to fix it, and summit a PR if find a solution, meanwhile I just post this.

Thanks a bunch.

bojkomatias avatar Oct 13 '23 02:10 bojkomatias

Maybe related, the html plugin seems to be throwing a type error I did not encounter before, but could be related to a recent bun update

No overload matches this call.
     The last overload gave the following error.
       Argument of type 'Elysia<"", { request: { html: <A = void>(value: Readable | Element | ((this: void, rid: number, ...args: A[]) => Element), ...args: A[]) => string | Response | Promise<...>; }; store: {}; }, { ...; }, {}, {}, false>' is not assignable to parameter of type 'Promise<{ default: Elysia<any, any, any, any, any, any>; }>'.
         Type 'Elysia<"", { request: { html: <A = void>(value: Readable | Element | ((this: void, rid: number, ...args: A[]) => Element), ...args: A[]) => string | Response | Promise<...>; }; store: {}; }, { ...; }, {}, {}, false>' is missing the following properties from type 'Promise<{ default: Elysia<any, any, any, any, any, any>; }>': then, catch, finally, [Symbol.toStringTag]

image

adicco avatar Oct 13 '23 12:10 adicco

(and I am also having issues with my afterHandle handlers not being executed)

adicco avatar Oct 13 '23 12:10 adicco

I cannot make it work, tried not using autoDetect false, but the fact that de GlobalHook runs before the LocalHook, with an early return fucks me over. Maybe the order of execution could be swaped to avoid this issues?

I believe truly granular > global is better in most use cases for better management of flow.

bojkomatias avatar Oct 16 '23 22:10 bojkomatias

I would also expect a local afterHandle to run, rather than having to guess which global plugin exited early.

adicco avatar Oct 17 '23 05:10 adicco

Did you find a workaround? This still happens to me with "@elysiajs/html": "0.8.0" and "elysia": "0.8.8".

JakeHedman avatar Jan 10 '24 10:01 JakeHedman

Looking or a workaround for onAfterHandle() not running I ended up here. Although not the same issue, what worked for me was to use(html()) right before the listen() call. That may work for you too, @JakeHedman.

chirvo avatar Jul 18 '24 07:07 chirvo

This issues should have been solved since 0.8 with an introduction of mapResponse

So what happens here is that prior to 0.8, the HTML plugin depends on afterHandle to transform the response to HTML which causes other afterHandle to not perform as called by HTML with a successful response, thus skipping all the rest.

Please let me know if this works on the latest or not, thanks.

SaltyAom avatar Jul 18 '24 07:07 SaltyAom