Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

middy/validator : How to format errors in proper json format #720

Closed
niveditavijayvargiya opened this issue Sep 8, 2021 · 7 comments
Closed

Comments

@niveditavijayvargiya
Copy link

I am using middy/validator for validating input request with httpErrorHandler, but it giving message 'Event object failed validation' response only.
I was expecting that it will show proper error field and its respective error.

BadRequestError: Event object failed validation
at createError (D:\Project\BoxSmart POC\middy-poc\node_modules@middy\util\index.js:259:10)
at validatorMiddlewareBefore (D:\Project\BoxSmart POC\middy-poc\node_modules@middy\validator\index.js:53:21)
at runMiddlewares (D:\Project\BoxSmart POC\middy-poc\node_modules@middy\core\index.js:120:88)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async runRequest (D:\Project\BoxSmart POC\middy-poc\node_modules@middy\core\index.js:80:5)
at async InProcessRunner.run (D:\Project\BoxSmart POC\middy-poc\node_modules\serverless-offline\dist\lambda\handler-runner\in-process-runner\InProcessRunner.js:213:24)
at async LambdaFunction.runHandler (D:\Project\BoxSmart POC\middy-poc\node_modules\serverless-offline\dist\lambda\LambdaFunction.js:355:20)
at async hapiHandler (D:\Project\BoxSmart POC\middy-poc\node_modules\serverless-offline\dist\events\http\HttpServer.js:602:18)
at async exports.Manager.execute (D:\Project\BoxSmart POC\middy-poc\node_modules@hapi\hapi\lib\toolkit.js:60:28)
at async Object.internals.handler (D:\Project\BoxSmart POC\middy-poc\node_modules@hapi\hapi\lib\handler.js:46:20)
at async exports.execute (D:\Project\BoxSmart POC\middy-poc\node_modules@hapi\hapi\lib\handler.js:31:20)
at async Request._lifecycle (D:\Project\BoxSmart POC\middy-poc\node_modules@hapi\hapi\lib\request.js:372:32)
at async Request._execute (D:\Project\BoxSmart POC\middy-poc\node_modules@hapi\hapi\lib\request.js:280:9) {
details: [
{
instancePath: '/body/password',
schemaPath: '#/properties/body/properties/password/minLength',
keyword: 'minLength',
params: [Object],
message: 'must NOT be shorter than 8 characters'
}
]
}

@AndrewCathcart
Copy link

Also interested in how we can format the error.

@willfarrell
Copy link
Member

By default middy won't leak internal information for security reasons. You need to expose the errors yourself. Because there are multiple standards and ways to do this we don't include it by default. You can access them from request.error.details. I've added a note to the README to help others. Let me know if more is required.

If you'd like an example, have a look at: https://github.com/willfarrell/middy-jsonapi/blob/main/index.js#L69

If you'd like to share your middleware for handling @middy/validator errors I'd be happy to review a PR to included it to our community list.

@niveditavijayvargiya
Copy link
Author

Thanks, I figured out my solution. I have created my own custom middleware for this.

@morcs
Copy link

morcs commented Oct 26, 2022

It took me a while to understand how to do this, so hopefully the following (TypeScript) example helps. To be placed in-between use(validator()) and use(httpErrorHandler()).

.use({
  onError: (request) => {
    const response = request.response;
    const error = <any>request.error;
    if (response.statusCode != 400) return;
    if (!error.expose || !error.cause) return;
    response.headers["Content-Type"] = "application/json";
    response.body = JSON.stringify({ message: response.body, validationErrors: error.cause });
  },
})

@willfarrell
Copy link
Member

@morcs Would you like to open a PR to have this example added to the docs?

@capndave
Copy link

Here's a version of the above that doesn't require @middy/http-error-handler to be part of the chain (if you need it somewhere that http-error-handler hasn't transformed yet). @willfarrell Please let me know if you think this should be added to the docs (I didn't see the other example anywhere) or written as a 3rd-party middleware.

Custom Middleware File

// custom-middleware.js
export const validationErrorJSONFormatter = () => ({
	onError: (request) => {
		const error = request.error;

		if (error.expose && error.statusCode === 400) {
			request.response = {
				statusCode: 400,
				body: JSON.stringify({
					message: error.message,
					validationErrors: error.cause,
				}),
				headers: { "Content-Type": "application/json" },
			};
		}
	},
});

Use the custom middleware

import {validationErrorJSONFormatter} from './custom-middleware'
import schema from './schema'

middy()
	.use(validationErrorJSONFormatter())
	.use(
		validatorMiddleware({
			eventSchema: transpileSchema(schema, { verbose: true }),
		})
	)

@ahmedShaheer3
Copy link

ahmedShaheer3 commented Jun 13, 2023

// validator Error type
interface validatorError {
instancePath: string;
schemaPath: string;
keyword: string;
params?: {
comparison?: string,
limit: 4
};
message: string;
}

export default (handler: Handler, eventSchema: object = {}): middy.MiddyfiedHandler =>
middy(handler).use([
httpJsonBodyParser(),
validator({eventSchema: transpileSchema(eventSchema)}),
{
onError: (request: any) => {
console.log('request in middy is', request);
const response = request.response;
const error = request.error;

    // checking if error is coming from validator
    if (response.statusCode != 400) return;
    if (!error.expose || !error.cause) return;

    // formating incoming validator error
    let validatorError: validatorError = error.cause[0];

    // getting error body path variable
    let errorParam: string[] = validatorError?.instancePath?.split('/');

    // creating custome message to show as error
    let customeErrorMsg = 'validation check fail on ' + errorParam[errorParam?.length - 1];

    response.headers['Content-Type'] = 'application/json';
    response.body = JSON.stringify({
      message: validatorError.message,
      validationErrors: customeErrorMsg,
    });
  },
},
httpErrorHandler(),
httpEventNormalizer(),
httpHeaderNormalizer(),
cors(),

]);``

Following the above @morcs comment i have apply some more formation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants