Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
nounderline opened this issue Oct 24, 2022 · 16 comments
Open
Labels
bug Something isn't working

Comments

@nounderline
Copy link

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 } })
  1. 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.

@nounderline nounderline added the bug Something isn't working label Oct 24, 2022
@soedirgo soedirgo transferred this issue from supabase/supabase-js Oct 25, 2022
@bombillazo
Copy link
Contributor

bombillazo commented Jun 9, 2023

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:

} catch (error) {
return { data: null, error }
}

That said, the error returned in the payload has a context property that should contain the causing error:

const response = await this.fetch(`${this.url}/${functionName}`, {
method: method || 'POST',
// headers priority is (high to low):
// 1. invoke-level headers
// 2. client-level headers
// 3. default Content-Type header
headers: { ..._headers, ...this.headers, ...headers },
body,
}).catch((fetchError) => {
throw new FunctionsFetchError(fetchError)
})
const isRelayError = response.headers.get('x-relay-error')
if (isRelayError && isRelayError === 'true') {
throw new FunctionsRelayError(response)
}
if (!response.ok) {
throw new FunctionsHttpError(response)
}

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

@dts
Copy link

dts commented Dec 28, 2023

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
Copy link

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

@williamlmao
Copy link

+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
Copy link

ghost commented Feb 12, 2024

+1

4 similar comments
@skhetcho
Copy link

+1

@dominik-rehse
Copy link

+1

@branaust
Copy link

+1

@lavisht22
Copy link

+1

@pariah140
Copy link

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
Copy link

+1

@AwakenedMind
Copy link

+!

@vrijmetse
Copy link

+1

@morksen123
Copy link

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
Copy link

+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
Copy link

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)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests