swagger-api / swagger-node

Swagger module for node.js
http://swagger.io
Apache License 2.0
3.97k stars 585 forks source link

override default swagger error structure #385

Open ugolas opened 8 years ago

ugolas commented 8 years ago

Hi,

In my API there is a specific error structure which I must return.

But when swagger input validation fails, the error returned is in the format: { "message": "Request validation failed: Parameter (token) is required", "code": "REQUIRED", "failedValidation": true, "path": [ "paths", "/payments", "get", "parameters", "0" ], "paramName": "token" }

Is there a way to override this structure and construct a different error structure (for example - take the message from the swagger response and add it to my error structure?)

Or just by intercepting the response and in case of an error map it to my error?

clarke07 commented 8 years ago

From what I know, inside your config: default.yaml, you have

swagger_controllers:
 - onError: json_error_handler

if you remove this line, you will be ok to use your own error handler.

But I got another issue. In my app.js, I have

SwaggerExpress.create(config, (err, swaggerExpress) => {
  ......
  app.use(SwaggerUi(swaggerExpress.runner.swagger)); // visit swagger ui at '/docs'
  swaggerExpress.register(app);
  app.use(customErrorHandler);
  ......
  let port = config.port,
    domain = config.domain;
  app.listen(port);
  ......
});

Then in my controller, whenever an error, I do next({ status: XXX, code: XXX, message: XXX }); But inside my customErrorHandler, the err is no longer a json but a error object like:

Error: {\"status\":XXX,\"code\":XXX,\"message\":\"message\"}
  at Bagpipes.handleError (/usr/src/app/node_modules/bagpipes/lib/bagpipes.js:184:35)
  at /usr/src/app/node_modules/bagpipes/lib/bagpipes.js:173:32
  at templateController.js:53:16
  at run (/usr/src/app/node_modules/core-js/modules/es6.promise.js:89:22)
  at /usr/src/app/node_modules/core-js/modules/es6.promise.js:102:28  
  at flush (/usr/src/app/node_modules/core-js/modules/_microtask.js:18:9)
  at _combinedTickCallback (internal/process/next_tick.js:67:7)
  at process._tickDomainCallback (internal/process/next_tick.js:122:9)

It seems still swagger pipes did something to the payload I pass to next and created an Error object before the err reaches my customErrorHandler. How could I skip this part?

Solution: when do return next(err), err must be an Error object otherwise swagger will transfer it to error object. So to customize error, better do

let newError  = new Error('message')
newError.A = A;
newError.B = B;
return next(newError)

Then the error handler can catch it and retrieve all key-value properties.