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

feat: throw on error types #494

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
24 changes: 11 additions & 13 deletions src/PostgrestBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
// @ts-ignore
import nodeFetch from '@supabase/node-fetch'

import type { Fetch, PostgrestSingleResponse } from './types'
import type { Fetch, PostgrestResponseSuccess, PostgrestSingleResponse } from './types'
import PostgrestError from './PostgrestError'

export default abstract class PostgrestBuilder<Result>
export default abstract class PostgrestBuilder<Result, ThrowOnError extends boolean = false>
implements PromiseLike<PostgrestSingleResponse<Result>>
{
protected method: 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'DELETE'
protected url: URL
protected headers: Record<string, string>
protected schema?: string
protected body?: unknown
protected shouldThrowOnError = false
protected shouldThrowOnError: boolean
protected signal?: AbortSignal
protected fetch: Fetch
protected isMaybeSingle: boolean

constructor(builder: PostgrestBuilder<Result>) {
constructor(builder: PostgrestBuilder<Result, ThrowOnError>) {
this.method = builder.method
this.url = builder.url
this.headers = builder.headers
Expand All @@ -36,20 +36,18 @@ export default abstract class PostgrestBuilder<Result>
}
}

/**
* If there's an error with the query, throwOnError will reject the promise by
* throwing the error instead of returning it as part of a successful response.
*
* {@link https://github.com/supabase/supabase-js/issues/92}
*/
throwOnError(): this {
throwOnError(): PostgrestBuilder<Result, true> {
this.shouldThrowOnError = true
return this
return this as PostgrestBuilder<Result, true>
}

then<TResult1 = PostgrestSingleResponse<Result>, TResult2 = never>(
onfulfilled?:
| ((value: PostgrestSingleResponse<Result>) => TResult1 | PromiseLike<TResult1>)
| ((
value: ThrowOnError extends true
? PostgrestResponseSuccess<Result>
: PostgrestSingleResponse<Result>
) => TResult1 | PromiseLike<TResult1>)
| undefined
| null,
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
Expand Down
51 changes: 43 additions & 8 deletions src/PostgrestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ export default class PostgrestClient<
: string & keyof Database,
Schema extends GenericSchema = Database[SchemaName] extends GenericSchema
? Database[SchemaName]
: any
: any,
ThrowOnError extends boolean = false
> {
url: string
headers: Record<string, string>
schemaName?: SchemaName
fetch?: Fetch
shouldThrowOnError: ThrowOnError

// TODO: Add back shouldThrowOnError once we figure out the typings
/**
Expand All @@ -44,36 +46,64 @@ export default class PostgrestClient<
headers = {},
schema,
fetch,
shouldThrowOnError,
}: {
headers?: Record<string, string>
schema?: SchemaName
fetch?: Fetch
shouldThrowOnError?: ThrowOnError
} = {}
) {
this.url = url
this.headers = { ...DEFAULT_HEADERS, ...headers }
this.schemaName = schema
this.fetch = fetch
this.shouldThrowOnError = Boolean(shouldThrowOnError) as ThrowOnError
}

throwOnError(): PostgrestClient<Database, SchemaName, Schema, true> {
return new PostgrestClient(this.url, {
headers: this.headers,
schema: this.schemaName,
fetch: this.fetch,
shouldThrowOnError: true,
}) as PostgrestClient<Database, SchemaName, Schema, true>
}

from<
TableName extends string & keyof Schema['Tables'],
Table extends Schema['Tables'][TableName]
>(relation: TableName): PostgrestQueryBuilder<Schema, Table, TableName>
>(
relation: TableName
): PostgrestQueryBuilder<
Schema,
Table,
any,
Table extends { Relationships: infer R } ? R : unknown,
ThrowOnError
>
from<ViewName extends string & keyof Schema['Views'], View extends Schema['Views'][ViewName]>(
relation: ViewName
): PostgrestQueryBuilder<Schema, View, ViewName>
): PostgrestQueryBuilder<
Schema,
View,
any,
View extends { Relationships: infer R } ? R : unknown,
ThrowOnError
>
from(relation: string): PostgrestQueryBuilder<Schema, any, any, any, ThrowOnError>
/**
* Perform a query on a table or a view.
*
* @param relation - The table or view name to query
*/
from(relation: string): PostgrestQueryBuilder<Schema, any, any> {
from(relation: string): PostgrestQueryBuilder<Schema, any, any, any, ThrowOnError> {
const url = new URL(`${this.url}/${relation}`)
return new PostgrestQueryBuilder(url, {
return new PostgrestQueryBuilder<Schema, any, any, any, ThrowOnError>(url, {
headers: { ...this.headers },
schema: this.schemaName,
fetch: this.fetch,
shouldThrowOnError: this.shouldThrowOnError,
})
}

Expand All @@ -89,12 +119,14 @@ export default class PostgrestClient<
): PostgrestClient<
Database,
DynamicSchema,
Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any
Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any,
ThrowOnError
> {
return new PostgrestClient(this.url, {
headers: this.headers,
schema,
fetch: this.fetch,
shouldThrowOnError: this.shouldThrowOnError,
})
}

Expand Down Expand Up @@ -140,7 +172,9 @@ export default class PostgrestClient<
? Fn['Returns'][number]
: never
: never,
Fn['Returns']
Fn['Returns'],
unknown,
ThrowOnError
> {
let method: 'HEAD' | 'GET' | 'POST'
const url = new URL(`${this.url}/rpc/${fn}`)
Expand Down Expand Up @@ -174,6 +208,7 @@ export default class PostgrestClient<
body,
fetch: this.fetch,
allowEmpty: false,
} as unknown as PostgrestBuilder<Fn['Returns']>)
shouldThrowOnError: this.shouldThrowOnError,
} as never)
}
}
12 changes: 10 additions & 2 deletions src/PostgrestFilterBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,16 @@ export default class PostgrestFilterBuilder<
Row extends Record<string, unknown>,
Result,
RelationName = unknown,
Relationships = unknown
> extends PostgrestTransformBuilder<Schema, Row, Result, RelationName, Relationships> {
Relationships = unknown,
ThrowOnError extends boolean = false
> extends PostgrestTransformBuilder<
Schema,
Row,
Result,
RelationName,
Relationships,
ThrowOnError
> {
eq<ColumnName extends string & keyof Row>(
column: ColumnName,
value: NonNullable<Row[ColumnName]>
Expand Down