supabase / functions-js

MIT License
62 stars 22 forks source link

supabase.functions.invoke returns null data when response is non-2xxx #45

Open nounder opened 1 year ago

nounder commented 1 year ago

Bug report

Describe the bug

When calling supabase.functions.invoke to a function that responds with non-2xx status code following error is returned with null data:

FunctionsHttpError: Edge Function returned a non-2xx status code

Supabase gives full freedom on how Edge Functions are implemented without enforcing any schema. However, supabase-js is enforcing some response schema because it discards response body when status is non-2xx.

To Reproduce

  1. Deploy Edge functions that returns
    return new Response("Malformed request", { headers: { status: Status.BadRequest } })
  2. Call supabase.functions.invoke to it and see that data is null.

Expected behavior

data is available when Edge Functions responds with non-2xx response.

bombillazo commented 1 year ago

This and #55 are pretty much duplicates, I explained in the other Issue why its happening.

In this specific issue, the client checks if any errors happened during the fetch, if it has a RelayError, or if the response did not return a 2xx response. If any of these happen, the client will directly skip the data response and only return the error thrown internally inside the client, not the error causing throw:

https://github.com/supabase/functions-js/blob/af4113a3368f812f491dfac0c1482460698dfdd1/src/FunctionsClient.ts#L115-L117

That said, the error returned in the payload has a context property that should contain the causing error: https://github.com/supabase/functions-js/blob/af4113a3368f812f491dfac0c1482460698dfdd1/src/FunctionsClient.ts#L80-L99

Depending on the source, you'll get the response or the fetch error.

dts commented 8 months ago

Perhaps relevant, when testing error states using Deno test, if you don't await the error.context.json() (or not JSON, if you have a non-json endpoint), you can a gross (and somewhat confusing) test failure:

 ERRORS 

legacy-auth ... test name => https://deno.land/std@0.210.0/testing/_test_suite.ts:323:15
error: Leaking resources:
  - A fetch response body (rid 22) was created during the test, but not consumed during the test. Consume or close the response body `ReadableStream`, e.g `await resp.text()` or `await resp.body.cancel()`.

 FAILURES 
Mihai-github commented 8 months ago

Still happening is there any live solution or we still waiting for official fix?

williamlmao commented 8 months ago

+1 on this issue. Its making it difficult to debug things in production as our sentry errors just show edge Function returned a non-2xx status code

ghost commented 7 months ago

+1

skhetcho commented 7 months ago

+1

dominik-rehse commented 6 months ago

+1

branaust commented 6 months ago

+1

lavisht22 commented 6 months ago

+1

pariah140 commented 6 months ago

This is baffling. I am also getting this response but I know from the function code that is definitely intending to return a 200 status.

Suzan-Dev commented 6 months ago

+1

AwakenedMind commented 5 months ago

+!

vrijmetse commented 5 months ago

+1

morksen123 commented 5 months ago

I debugged using the error handling code snippet below. Turns out I did not have the right authentication for my edge function. I added the secret key for my new edge function. Hope this helps!

if (error instanceof FunctionsHttpError) { const errorMessage = await error.context.json() console.log('Function returned an error', errorMessage) } else if (error instanceof FunctionsRelayError) { console.log('Relay error:', error.message) } else if (error instanceof FunctionsFetchError) { console.log('Fetch error:', error.message) }

laurencebedford commented 5 months ago

+1 im using a rate limit and I send a 429 response and we again "FunctionsHttpError: Edge Function returned a non-2xx status" we cannot even pull the status code since error.code provides an undefined value.

bettysteger commented 4 months ago

If anyone comes here and just want to show the error, this was my solution: https://supabase.com/docs/guides/functions/quickstart#error-handling

import { FunctionsHttpError } from '@supabase/supabase-js'

const { data, error } = await supabase.functions.invoke('...')

if (error && error instanceof FunctionsHttpError) {
  const errorMessage = await error.context.json()
  console.log('Function returned an error', errorMessage)
}