From 263d843f4299c4a68356101ba0e96eeac10ea0dc Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Wed, 21 Jun 2023 19:33:39 +0800 Subject: [PATCH] fix: rest api should return error reason --- packages/server/src/api/rest/index.ts | 5 +++-- packages/server/tests/api/rest.test.ts | 28 +++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/server/src/api/rest/index.ts b/packages/server/src/api/rest/index.ts index 89bad6b6d..31da0fcde 100644 --- a/packages/server/src/api/rest/index.ts +++ b/packages/server/src/api/rest/index.ts @@ -1505,7 +1505,7 @@ class RequestHandler { private handlePrismaError(err: unknown) { if (isPrismaClientKnownRequestError(err)) { if (err.code === 'P2004') { - return this.makeError('forbidden'); + return this.makeError('forbidden', undefined, 403, err.meta?.reason as string); } else if (err.code === 'P2025' || err.code === 'P2018') { return this.makeError('notFound'); } else { @@ -1530,7 +1530,7 @@ class RequestHandler { } } - private makeError(code: keyof typeof this.errors, detail?: string, status?: number) { + private makeError(code: keyof typeof this.errors, detail?: string, status?: number, reason?: string) { return { status: status ?? this.errors[code].status, body: { @@ -1540,6 +1540,7 @@ class RequestHandler { code: paramCase(code), title: this.errors[code].title, detail: detail || this.errors[code].detail, + reason, }, ], }, diff --git a/packages/server/tests/api/rest.test.ts b/packages/server/tests/api/rest.test.ts index 4a8598bf9..1280c15ee 100644 --- a/packages/server/tests/api/rest.test.ts +++ b/packages/server/tests/api/rest.test.ts @@ -1,11 +1,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /// -import { loadSchema, run } from '@zenstackhq/testtools'; +import { withPolicy } from '@zenstackhq/runtime'; +import { CrudFailureReason } from '@zenstackhq/runtime/constants'; import { ModelMeta } from '@zenstackhq/runtime/enhancements/types'; +import { loadSchema, run } from '@zenstackhq/testtools'; import makeHandler from '../../src/api/rest'; import { Response } from '../../src/types'; -import { withPolicy } from '@zenstackhq/runtime'; let prisma: any; let zodSchemas: any; @@ -1844,6 +1845,13 @@ describe('REST server tests - enhanced prisma', () => { @@allow('create,read', true) @@allow('update', value > 0) } + + model Bar { + id Int @id + value Int + + @@allow('create', true) + } `; beforeAll(async () => { @@ -1862,7 +1870,7 @@ describe('REST server tests - enhanced prisma', () => { run('npx prisma db push'); }); - it('policy rejection test', async () => { + it('update policy rejection test', async () => { let r = await handler({ method: 'post', path: '/foo', @@ -1885,6 +1893,20 @@ describe('REST server tests - enhanced prisma', () => { }); expect(r.status).toBe(403); }); + + it('read-back policy rejection test', async () => { + const r = await handler({ + method: 'post', + path: '/bar', + query: {}, + requestBody: { + data: { type: 'bar', attributes: { id: 1, value: 0 } }, + }, + prisma, + }); + expect(r.status).toBe(403); + expect((r.body as any).errors[0].reason).toBe(CrudFailureReason.RESULT_NOT_READABLE); + }); }); describe('REST server tests - NextAuth project regression', () => {