From f730aa793fbc8650de8bf914c816e943eba42844 Mon Sep 17 00:00:00 2001 From: Julian Meyer Date: Sun, 14 Jan 2024 21:16:38 -0800 Subject: [PATCH] fix: Ensure thrown errors have a stack trace (#502) * Ensure thrown errors have a stack trace * chore: stricter typing * chore: update snapshot --------- Co-authored-by: Bobbie Soedirgo --- src/PostgrestBuilder.ts | 3 ++- src/PostgrestError.ts | 15 +++++++++++++++ test/basic.ts | 20 ++++++++++++-------- 3 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 src/PostgrestError.ts diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index 23e397f1..96a8bc55 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -2,6 +2,7 @@ import nodeFetch from '@supabase/node-fetch' import type { Fetch, PostgrestSingleResponse } from './types' +import PostgrestError from './PostgrestError' export default abstract class PostgrestBuilder implements PromiseLike> @@ -156,7 +157,7 @@ export default abstract class PostgrestBuilder } if (error && this.shouldThrowOnError) { - throw error + throw new PostgrestError(error) } } diff --git a/src/PostgrestError.ts b/src/PostgrestError.ts new file mode 100644 index 00000000..8253ae96 --- /dev/null +++ b/src/PostgrestError.ts @@ -0,0 +1,15 @@ +import type { PostgrestError as IPostgrestError } from './types' + +export default class PostgrestError extends Error implements IPostgrestError { + details: string + hint: string + code: string + + constructor(context: IPostgrestError) { + super(context.message) + this.name = 'PostgrestError' + this.details = context.details + this.hint = context.hint + this.code = context.code + } +} diff --git a/test/basic.ts b/test/basic.ts index 0c948828..9a170019 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -631,20 +631,24 @@ test('throwOnError throws errors instead of returning them', async () => { try { await postgrest.from('missing_table').select().throwOnError() } catch (error) { - expect(error).toMatchInlineSnapshot(` - Object { - "code": "42P01", - "details": null, - "hint": null, - "message": "relation \\"public.missing_table\\" does not exist", - } - `) + expect(error).toMatchInlineSnapshot( + `[PostgrestError: relation "public.missing_table" does not exist]` + ) isErrorCaught = true } expect(isErrorCaught).toBe(true) }) +test('throwOnError throws errors which include stack', async () => { + try { + await postgrest.from('does_not_exist').select().throwOnError() + } catch (err) { + expect(err instanceof Error).toBe(true) + expect((err as Error).stack).not.toBeUndefined() + } +}) + // test('throwOnError setting at the client level - query', async () => { // let isErrorCaught = false // const postgrest_ = new PostgrestClient(REST_URL, { throwOnError: true })