grammyjs / grammY

The Telegram Bot Framework.
https://grammy.dev
MIT License
2.38k stars 118 forks source link

Investigate having to access `req.headers` on Deno to prevent requests from being closed #350

Open sparfenyuk opened 1 year ago

sparfenyuk commented 1 year ago

Tried to play around this example. It basically doesn't work as expected. I am getting the following errors in Supabase dashboard:

TypeError: cannot read headers: request closed
    at Object.get headerList (deno:ext/fetch/23_request.js:116:19)
    at Request.request.<computed> (deno:ext/fetch/23_request.js:583:62)
    at Request.get [headers] (deno:ext/fetch/23_request.js:252:48)
    at Request.get headers (deno:ext/fetch/23_request.js:467:18)
    at stdHttp (https://deno.land/x/grammy@v1.13.0/convenience/frameworks.shared.ts:40:21)
    at https://deno.land/x/grammy@v1.13.0/convenience/webhook.ts:29:85
    at async Server.<anonymous> (file:///src/index.ts:14:16)
    at async Server.#respond (https://deno.land/std@0.170.0/http/server.ts:220:24)
TypeError: Cannot read properties of undefined (reading 'bodyUsed')
    at Server.#respond (https://deno.land/std@0.170.0/http/server.ts:221:26)

Note: My edge function works only if grammy is downgraded to 1.8.3.

KnorpelSenf commented 1 year ago

Is 1.8.3 the latest version that works? In other words, does this issue already occur with 1.9.0?

sparfenyuk commented 1 year ago

1.8.3 is the latest, yes.

sparfenyuk commented 1 year ago

Besides, if I post to an endpoint directly using curl, I am getting the 401 Unauthorized:

HTTP/1.1 401 Unauthorized
content-encoding: gzip
content-type: text/plain;charset=UTF-8
date: Tue, 03 Jan 2023 14:13:37 GMT
server: deno/gcp-europe-central2
transfer-encoding: chunked
vary: Accept-Encoding
via: http/1.1 edgeproxy

secret token is wrong

What secret token is meant here?

sparfenyuk commented 1 year ago

OK, I got my bot fixed.

Regarding 'secret token is wrong' error, I must pass in the corresponding value to webhookCallback(...) as secretToken argument. I suppose, the error message could be more informative.

The initial problem with cannot read headers: request closed is solved by introducing a line of console.log(req.headers) right before calling a request handler, which looks suspicious, for sure. Actually, the similar workaround I found in the grammy code itself: https://github.com/grammyjs/grammY/blob/9aed1336afdc4bec4b77751df07c82617a05e120/src/convenience/webhook.ts#L142-L147

KnorpelSenf commented 1 year ago

Fascinating. Glad to see you found the root cause of the problem.

Do you think https://grammy.dev/hosting/supabase.html can be improved to include the relevant information?

Actually, the similar workaround I found in the grammy code

Yes, it's still kinda annoying. I'm sure there must be a way to get rid of this. I'd be happy to hear about it if you find anything useful :)

sparfenyuk commented 1 year ago

Do you think https://grammy.dev/hosting/supabase.html can be improved to include the relevant information?

This is up to you. I am unclear about the issue. I tried to log something else, but only req.headers worked. Additionally, I'm not sure if it's a common problem.

KnorpelSenf commented 1 year ago

This is one of these edge cases that @KnightNiwrem might enjoy spending time on

KnorpelSenf commented 1 year ago

@sparfenyuk can you check if this still happens with the latest version of grammY? I assume so, but I'd just like to make sure this is still an issue before putting any time into it

gHashTag commented 6 months ago

I have this problem when I run Grammy in Supabase Edge functions

[Error] TypeError: cannot read headers: request closed
    at get headerList (ext:deno_fetch/23_request.js:118:17)
    at request.<computed> (ext:deno_fetch/23_request.js:571:60)
    at get [headers] (ext:deno_fetch/23_request.js:253:46)
    at get headers (ext:deno_fetch/23_request.js:453:16)
    at stdHttp (https://deno.land/x/grammy@v1.23.0/convenience/frameworks.ts:224:17)
    at https://deno.land/x/grammy@v1.23.0/convenience/webhook.ts:24:75
    at Object.handler (file:///home/deno/functions/ai-koshey/index.ts:347:18)
    at respond (ext:sb_core_main_js/js/http.js:162:38)
    at handleHttp (ext:sb_core_main_js/js/http.js:122:5)
    at eventLoopTick (ext:core/01_core.js:64:7)

runtime has escaped from the event loop unexpectedly: event loop error: Interrupted: operation canceled
    at async readableStreamCollectIntoUint8Array (ext:deno_web/06_streams.js:1074:19)
    at async consumeBody (ext:deno_fetch/22_body.js:241:9)
failed to send request to user worker: request has been cancelled by supervisor
user worker failed to respond: request has been cancelled by supervisor
WorkerRequestCancelled: request has been cancelled by supervisor
    at async Promise.allSettled (index 1)
    at async UserWorker.fetch (ext:sb_user_workers/user_workers.js:77:21)
    at async Object.handler (file:///home/deno/main/index.ts:165:14)
    at async respond (ext:sb_core_main_js/js/http.js:162:14) {
  name: "WorkerRequestCancelled"
Снимок экрана 2024-05-13 в 18 55 18
KnorpelSenf commented 6 months ago

Did you ever forget to use await on an async operation inside your middleware?

Vondollie commented 5 months ago

I got the same problem. Also with supabase edge functions. sparfenyuk's solution with console.log(req.headers) works

KnorpelSenf commented 5 months ago

Sounds like we should report this bug to Deno

alire2a commented 2 months ago

i have the exact same problem at the exact same situation with grammy and supabase edge function!

image

KnorpelSenf commented 2 months ago

Somebody needs to:

@alire2a do you want to be this somebody?

mxmalykhin commented 2 months ago

I had the same problem and I solved it with this:

return await handleUpdate(req.clone());
KnorpelSenf commented 2 months ago

Interesting stuff, perhaps we should do this, too

shivamklr commented 2 weeks ago

Here are the errors I in the Edge Logs

Webhook error: TypeError: cannot read headers: request closed
    at get headerList (ext:deno_fetch/23_request.js:125:17)
    at request.<computed> (ext:deno_fetch/23_request.js:595:60)
    at get [headers] (ext:deno_fetch/23_request.js:260:46)
    at get headers (ext:deno_fetch/23_request.js:475:16)
    at stdHttp (https://deno.land/x/grammy@v1.30.0/convenience/frameworks.ts:241:17)
    at https://deno.land/x/grammy@v1.30.0/convenience/webhook.ts:24:75
    at Object.handler (file:///Users/admin/Projects/upwork/NBA%20Telegram%20Project/supabase/functions/telegram-bot/index.ts:186:18)
    at respond (ext:sb_core_main_js/js/http.js:163:38)
    at handleHttp (ext:sb_core_main_js/js/http.js:123:5)
    at eventLoopTick (ext:core/01_core.js:168:7)

My workaround to this problem was to

  1. Downgrade the grammY version to 1.8.3

Old

import { Bot, webhookCallback, InlineKeyboard, Context } from "https://deno.land/x/grammy@v1.30.0/mod.ts";

Fix

import { Bot, webhookCallback, InlineKeyboard, Context } from "https://deno.land/x/grammy@v1.8.3/mod.ts";
  1. Redeploy the function, it should work.
shivamklr commented 2 weeks ago

As per the reasoning behind this, it is a TypeError. This should be fixable in grammY, as this occurs when there's a mismatch between the expected type and the actual type of value or when trying to access properties or methods on undefined or null values. Will post here if I find something new.

KnorpelSenf commented 2 weeks ago

Thank you for investigating it. Our webhook handling is so simple that I don't know what could be wrong about it.

I have a feeling that the actual framework adapter is perfectly correct in how it implements request and response handling, and that the issue is caused by the order of operations that grammY performs on the adapter. The way this is done is a little complex, but if you have questions about it, drop me a message and I'll spend some time explaining it.

I'd like to see this fixed purely out of curiosity already.