functions-js
                                
                                 functions-js copied to clipboard
                                
                                    functions-js copied to clipboard
                            
                            
                            
                        supabase.functions.invoke returns null data when response is non-2xxx
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
- Deploy Edge functions that returns
return new Response("Malformed request", { headers: { status: Status.BadRequest } })
- Call supabase.functions.invoke to it and see that datais null.
Expected behavior
data is available when Edge Functions responds with non-2xx response.
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.
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/[email protected]/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 
Still happening is there any live solution or we still waiting for official fix?
+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
+1
+1
+1
+1
+1
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.
+1
+!
+1
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) }
+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.
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)
}
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) }
Note that if you return your error messages in text/plain format, you would have to use error.context.text() instead of .json()