Skip to content

Commit 5683c63

Browse files
committed
fix: return request body validation errors as JSON
Validation failures now respond with HTTP 400 and a JSON body { error: 'Request body validation failed', details: [...] }, matching the format used by the AdminForth core express server. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> AdminForth/1782/generated-with-cli-dockerfile-
1 parent d374ad6 commit 5683c63

1 file changed

Lines changed: 37 additions & 24 deletions

File tree

index.ts

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -832,22 +832,26 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
832832
schema: z.ZodType<T>,
833833
body: unknown,
834834
response: { setStatus: (code: number, message: string) => void },
835-
): T | null {
835+
): { ok: true; data: T } | { ok: false; error: { error: string; details: unknown } } {
836836
const parsed = schema.safeParse(body ?? {});
837837
if (!parsed.success) {
838-
response.setStatus(422, parsed.error.message);
839-
return null;
838+
response.setStatus(400, '');
839+
return {
840+
ok: false,
841+
error: { error: 'Request body validation failed', details: parsed.error.issues },
842+
};
840843
}
841-
return parsed.data;
844+
return { ok: true, data: parsed.data };
842845
}
843846

844847
setupEndpoints(server: IHttpServer) {
845848
server.endpoint({
846849
method: 'POST',
847850
path: `/plugin/${this.pluginInstanceId}/get_records`,
848851
handler: async ({ body, response }) => {
849-
const data = this.parseBody(getRecordsBodySchema, body, response);
850-
if (!data) return;
852+
const parsed = this.parseBody(getRecordsBodySchema, body, response);
853+
if ('error' in parsed) return parsed.error;
854+
const data = parsed.data;
851855
if (!Array.isArray(data.record)) {
852856
return { records: [] };
853857
}
@@ -873,8 +877,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
873877
method: 'POST',
874878
path: `/plugin/${this.pluginInstanceId}/get_old_data`,
875879
handler: async ({ body, response }) => {
876-
const data = this.parseBody(getOldDataBodySchema, body, response);
877-
if (!data) return;
880+
const parsed = this.parseBody(getOldDataBodySchema, body, response);
881+
if ('error' in parsed) return parsed.error;
882+
const data = parsed.data;
878883
const recordId = data.recordId;
879884
if (recordId === undefined || recordId === null) {
880885
return { ok: false, error: "Missing recordId" };
@@ -895,8 +900,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
895900
method: 'POST',
896901
path: `/plugin/${this.pluginInstanceId}/get_images`,
897902
handler: async ({ body, response }) => {
898-
const data = this.parseBody(getImagesBodySchema, body, response);
899-
if (!data) return;
903+
const parsed = this.parseBody(getImagesBodySchema, body, response);
904+
if ('error' in parsed) return parsed.error;
905+
const data = parsed.data;
900906
let images = [];
901907
if(data.record){
902908
for( const record of data.record ) {
@@ -916,8 +922,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
916922
method: 'POST',
917923
path: `/plugin/${this.pluginInstanceId}/update_fields`,
918924
handler: async ({ body, adminUser, headers, response }) => {
919-
const data = this.parseBody(updateFieldsBodySchema, body, response);
920-
if (!data) return;
925+
const parsed = this.parseBody(updateFieldsBodySchema, body, response);
926+
if ('error' in parsed) return parsed.error;
927+
const data = parsed.data;
921928
let isAllowedToSave: any = { ok: true, error: '' };
922929
if(this.options.isAllowedToSave) {
923930
isAllowedToSave = await this.options.isAllowedToSave({ record: {}, adminUser: adminUser, resource: this.resourceConfig });
@@ -1025,8 +1032,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
10251032
method: 'POST',
10261033
path: `/plugin/${this.pluginInstanceId}/get_image_generation_prompts`,
10271034
handler: async ({ body, headers, response }) => {
1028-
const data = this.parseBody(getImageGenerationPromptsBodySchema, body, response);
1029-
if (!data) return;
1035+
const parsed = this.parseBody(getImageGenerationPromptsBodySchema, body, response);
1036+
if ('error' in parsed) return parsed.error;
1037+
const data = parsed.data;
10301038
const Id = data.recordId || [];
10311039
const customPrompt = data.customPrompt || null;
10321040
const record = await this.adminforth.resource(this.resourceConfig.resourceId).get([Filters.EQ(this.resourceConfig.columns.find(c => c.primaryKey)?.name, Id)]);
@@ -1053,8 +1061,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
10531061
method: 'POST',
10541062
path: `/plugin/${this.pluginInstanceId}/create-job`,
10551063
handler: async ({ body, adminUser, headers, response }) => {
1056-
const data = this.parseBody(createJobBodySchema, body, response);
1057-
if (!data) return;
1064+
const parsed = this.parseBody(createJobBodySchema, body, response);
1065+
if ('error' in parsed) return parsed.error;
1066+
const data = parsed.data;
10581067
const { actionType, recordId, customPrompt, filterFilledFields, sessionIds } = data;
10591068
if (this.options.rateLimits) {
10601069
if (sessionIds && sessionIds.length > 0) {
@@ -1114,8 +1123,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
11141123
method: 'POST',
11151124
path: `/plugin/${this.pluginInstanceId}/get-job-status`,
11161125
handler: async ({ body, adminUser, headers, response }) => {
1117-
const data = this.parseBody(jobStatusBodySchema, body, response);
1118-
if (!data) return;
1126+
const parsed = this.parseBody(jobStatusBodySchema, body, response);
1127+
if ('error' in parsed) return parsed.error;
1128+
const data = parsed.data;
11191129
const jobId = data.jobId;
11201130
if (!jobId) {
11211131
response.setStatus(400);
@@ -1154,8 +1164,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
11541164
method: 'POST',
11551165
path: `/plugin/${this.pluginInstanceId}/update-rate-limits`,
11561166
handler: async ({ body, adminUser, headers, response }) => {
1157-
const data = this.parseBody(updateRateLimitsBodySchema, body, response);
1158-
if (!data) return;
1167+
const parsed = this.parseBody(updateRateLimitsBodySchema, body, response);
1168+
if ('error' in parsed) return parsed.error;
1169+
const data = parsed.data;
11591170
const actionType = data.actionType;
11601171
const sessionId = randomUUID();
11611172
this.sessionIds.add(sessionId);
@@ -1184,8 +1195,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
11841195
method: 'POST',
11851196
path: `/plugin/${this.pluginInstanceId}/compile_old_image_link`,
11861197
handler: async ({ body, adminUser, headers, response }) => {
1187-
const data = this.parseBody(compileOldImageLinkBodySchema, body, response);
1188-
if (!data) return;
1198+
const parsed = this.parseBody(compileOldImageLinkBodySchema, body, response);
1199+
if ('error' in parsed) return parsed.error;
1200+
const data = parsed.data;
11891201
const image = data.image;
11901202
const columnName = data.columnName;
11911203
if (!image) {
@@ -1216,8 +1228,9 @@ export default class BulkAiFlowPlugin extends AdminForthPlugin {
12161228
method: 'POST',
12171229
path: `/plugin/${this.pluginInstanceId}/get_filtered_ids`,
12181230
handler: async ({ body, adminUser, headers, query, cookies, requestUrl, response }) => {
1219-
const data = this.parseBody(getFilteredIdsBodySchema, body, response);
1220-
if (!data) return;
1231+
const parsed = this.parseBody(getFilteredIdsBodySchema, body, response);
1232+
if ('error' in parsed) return parsed.error;
1233+
const data = parsed.data;
12211234
const resource = this.resourceConfig;
12221235

12231236
for (const hook of resource.hooks?.list?.beforeDatasourceRequest || []) {

0 commit comments

Comments
 (0)