diff --git a/packages/nocodb/src/lib/meta/api/helpers/apiHelpers.ts b/packages/nocodb/src/lib/meta/api/helpers/apiHelpers.ts index 49d1fbc462..25a077a52d 100644 --- a/packages/nocodb/src/lib/meta/api/helpers/apiHelpers.ts +++ b/packages/nocodb/src/lib/meta/api/helpers/apiHelpers.ts @@ -2,6 +2,7 @@ import { NextFunction, Request, Response } from 'express'; import Ajv, { ErrorObject } from 'ajv'; // @ts-ignore import swagger from '../../../../schema/swagger.json'; +import { NcError } from '../../helpers/catchError' export function parseHrtimeToSeconds(hrtime) { const seconds = (hrtime[0] + hrtime[1] / 1e6).toFixed(3); @@ -29,10 +30,29 @@ export const getAjvValidatorMw = (schema) => { // If the request body is invalid, send a response with an error message res.status(400).json({ - status: 'error', message: 'Invalid request body', errors, }); } }; }; + +// a function to validate the payload against the schema +export const ajvValidator = (schema, payload) => { + // Validate the request body against the schema + const valid = ajv.validate( + typeof schema === 'string' ? { $ref: schema } : schema, + payload + ); + + // If the request body is not valid, throw error + if (!valid) { + const errors: ErrorObject[] | null | undefined = ajv.errors; + + // If the request body is invalid, throw error with error message and errors + NcError.ajvValidationError({ + message: 'Invalid request body', + errors, + }); + } +} diff --git a/packages/nocodb/src/lib/meta/helpers/catchError.ts b/packages/nocodb/src/lib/meta/helpers/catchError.ts index fdf1344638..f7d6f9dd4b 100644 --- a/packages/nocodb/src/lib/meta/helpers/catchError.ts +++ b/packages/nocodb/src/lib/meta/helpers/catchError.ts @@ -1,3 +1,5 @@ +import { ErrorObject } from 'ajv'; + enum DBError { TABLE_EXIST = 'TABLE_EXIST', TABLE_NOT_EXIST = 'TABLE_NOT_EXIST', @@ -409,6 +411,8 @@ export default function ( return res.status(500).json({ msg: e.message }); } else if (e instanceof NotImplemented) { return res.status(501).json({ msg: e.message }); + } else if (e instanceof AjvError) { + return res.status(501).json({ msg: e.message, errors: e.errors }); } next(e); } @@ -427,6 +431,15 @@ class InternalServerError extends Error {} class NotImplemented extends Error {} +class AjvError extends Error { + constructor(param: { message: string; errors: ErrorObject[] }) { + super(param.message); + this.errors = param.errors; + } + + errors: ErrorObject[]; +} + export class NcError { static notFound(message = 'Not found') { throw new NotFound(message); @@ -451,4 +464,8 @@ export class NcError { static notImplemented(message = 'Not implemented') { throw new NotImplemented(message); } + + static ajvValidationError(param: { message: string; errors: ErrorObject[] }) { + throw new AjvError(param); + } }