diff --git a/packages/plugin-error-handler/src/__tests__/render-error.test.ts b/packages/plugin-error-handler/src/__tests__/render-error.test.ts index e1a8a0612..6ec66af4c 100644 --- a/packages/plugin-error-handler/src/__tests__/render-error.test.ts +++ b/packages/plugin-error-handler/src/__tests__/render-error.test.ts @@ -1,9 +1,12 @@ import { MockServer, mockServer } from '@nocobase/test'; import { PluginErrorHandler } from '../server'; +import { Database } from '@nocobase/database'; +import supertest from 'supertest'; describe('create with exception', () => { let app: MockServer; beforeEach(async () => { app = mockServer(); + await app.cleanDb(); app.plugin(PluginErrorHandler); }); @@ -117,4 +120,51 @@ describe('create with exception', () => { ], }); }); + + it('should handle unique error with raw sql', async () => { + const userCollection = app.collection({ + name: 'users', + autoGenId: false, + timestamps: false, + fields: [ + { + name: 'name', + type: 'string', + primaryKey: true, + }, + ], + }); + + await app.loadAndInstall(); + + app.resourcer.define({ + name: 'test', + actions: { + async test(ctx) { + const db: Database = ctx.db; + + const sql = `INSERT INTO ${userCollection.model.tableName} (name) + VALUES (:name)`; + + await db.sequelize.query(sql, { + replacements: { name: ctx.action.params.values.name }, + type: 'INSERT', + }); + }, + }, + }); + + const agent = supertest.agent(app.callback()); + + await agent.post('/test:test').send({ + name: 'u1', + }); + + const response = await agent.post('/test:test').send({ + name: 'u1', + }); + + const body = response.body; + expect(body['errors'][0]['message']).toBeDefined(); + }); }); diff --git a/packages/plugin-error-handler/src/server.ts b/packages/plugin-error-handler/src/server.ts index d11f68c38..2313d21cc 100644 --- a/packages/plugin-error-handler/src/server.ts +++ b/packages/plugin-error-handler/src/server.ts @@ -20,6 +20,10 @@ export class PluginErrorHandler extends Plugin { registerSequelizeValidationErrorHandler() { const findFieldTitle = (instance, path, tFunc) => { + if (!instance) { + return path; + } + const model = instance.constructor; const collection = this.db.modelCollection.get(model); const field = collection.getField(path);