supabase-js: Major DX change: response and error handling
Decision
We’ve decided to make a major change to support a better developer experience for working with supabase-js. Instead of throwing an error, we will return the error object as part of the response.
Example
Given a successful query, e.g. const response = await supabase.from('products').select('*')
, response
will be:
{
"error": null,
"data": [...],
"status": 200,
"statusCode": 200,
"statusText": "",
"body": [...] // for backwards compatibility: `body === data`
}
Given a bad query, e.g. const response = await supabase.from('productx').select('*')
, response
will be:
{
"error": {
"code": 404,
"message": "relation \"public.productx\" does not exist",
"details": null,
"hint": null
},
"data": null,
"status": 404,
"statusCode": 404,
"statusText": "",
"body": null // for backwards compatibility: `body === data`
}
Future DX
This will enable the following experience:
const { error, data: products } = await supabase.from('products').select('*')
if (error) {
alert(error.message)
return // abort
}
console.log(`Found ${products.length} products.`)
Additional context
Inspiration has been taken from https://github.com/vercel/swr#quick-start:
import useSWR from 'swr'
function Profile() {
const { data, error } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
as well as Stripe.js : https://stripe.com/docs/js/payment_methods/create_payment_method
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 20
- Comments: 15 (8 by maintainers)
Commits related to this issue
- refactor: shape response format https://github.com/supabase/supabase-js/issues/32 — committed to soedirgo/postgrest-js by soedirgo 4 years ago
- Feature: migrate to typescript (#50) - Fixes #32 Major DX change: response and error handling - Fixes #49 When no `supabaseKey` is passed in it throws an error - Fixes #31 chore: set up semanti... — committed to supabase/supabase-js by kiwicopple 4 years ago
Throwing errors by default, or have that as an option on
createClient
, would be a great improvement for us too. We use a lot of rxjs with supabase and regular error throwing would make the whole process more logical. Now we have to remember to writethrowOnError
after every query, because otherwise the error will go silentCan we set this as a default behaviour globally via a parameter or smth? This is super unusual behaviour, as SDKs ussually throw errors, otherwise we have to add lots of additional checks around that which doesn’t make sense.
This is not specific to
.rpc()
. You can use.throwOnError()
on.select()
,.insert()
, etc. and it will throw errors instead of returning it in the response object. See the example I linked above.I don’t think this should be expected, just catch and rethrow unexpected errors. As you say, handling every possible error would be unwieldy. We should just shape expected errors.
This one is just a preference. I guess we should decide now what is the more appropriate name for the key. IMO
body
seems like a throwback to when we used ajax used to request HTML snippets that would be injected into HTML.I’d far prefer this one to look like the suggested change (
if (error)
). The termok
is unexpected, anderror
is very clear