Option to have supabase client throw error instead of returning it #604
-
Hey! So when we make a query with the supabase client, it might look something like: const { data, error } = await supabase
.from('cities')
.select('name, country_id')
.single() Any potential error (such as no rows returned, making const { data, error } = await supabase.from('cities').select('name, country_id').single()
if (error) throw new Error(error.message)
// Do stuff here Would it perhaps be possible to give the client an option, perhaps as part of initialization, so that it would throw these errors instead of just returning them as part of the result? You'd still have to catch the errors somewhere of course. There's nothing necessarily wrong with the current interface, it's just that it tends to get noisy I find. Especially when you do multiple queries where the subsequent ones depend on the previous. A transaction interface (see #526) would probably go a long way in alleviating this (while being better as well) but even so I think having the option would give us exception using plebs a nice option for control flow. :o) What'ya reckon? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
I was browsing around the code of supabase-js and postgres-js thinking maybe I could contribute a PR, and came across this little nugget in one of the comments: supabase/supabase-js#32 I know have a better understanding of why you've chosen this design – it makes sense. That said, I still believe having the option to have the promise reject instead of resolve if there's an error wouldn't hurt. I'm not advocating changing the default obviously, just for providing the option one way or another. Having looked at the code I think I understand how it all ties together. Initially I was thinking that providing an option in the supabase client constructor would be fine, and then just pushing that downward into the query builder. That would be the nuclear option, since it would change the behaviour of all queries and if you want to change it you'd have to initialize a new client. That could perhaps get confusing and a bit of a chore. Another perhaps better and easier to implement option, is to add a function to the protected _rejectErrors?: boolean = false
/**
* Reject errors instead of resolving them.
*
* The default behaviour is to always resolve the promise, even if there's
* an error. This function allows for changing this behavior such that if
* the response is an error, the promise will be rejected instead of resolved.
*
* @param reject When set to true, errors will be rejected.
*/
rejectErrors(reject: boolean = true): PostgresBuilder<T> {
this._rejectErrors = reject
}
then<TResult1 = PostgrestResponse<T>, TResult2 = never>(
onfulfilled?:
| ((value: PostgrestResponse<T>) => TResult1 | PromiseLike<TResult1>)
| undefined
| null,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
): PromiseLike<TResult1 | TResult2> {
// All the important stuff snipped for brevity
// This is the key bit, if `_rejectErrors` is true,
// reject the promise instead of satisfying it
const resolver = error && _rejectErrors? onrejected : onfulfilled
return resolver(postgrestResponse)
} I haven't thought this through very much and – as I'm sure you can tell – I'm not a TypeScript expert by any means so there's a very real chance the above makes no sense. But I hope the idea is clear any way, and if you think it has merit I'd be happy to contribute a PR for you to review. EDIT – usage would be like so: try {
const {data: [first, ...rest] } = await supabase
.from(‘sometable’)
.select(‘stuff’)
.eq(‘color’, ‘blue’)
.rejectErrors()
// do stuff with result data, which may be undefined because it is null,
// but that’s different from checking for errors
} catch ({ message, detail, hint }) {
// do error handling
} Penny for your thoughts? |
Beta Was this translation helpful? Give feedback.
-
Turns out there are others asking for pretty much the same thing, with different syntax, in supabase/supabase-js#92. |
Beta Was this translation helpful? Give feedback.
-
Is there any update on this? |
Beta Was this translation helpful? Give feedback.
Hi @pppdns! Yes, I contributed the
throwOnError
option some time ago: supabase/postgrest-js#188Essentially just tack on
.throwOnError()
to the end of any query and it should reject the promise if there's an error. Here's an example:Source: https://supabase.com/docs/guides/ai/examples/huggingface-image-captioning