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

Fixed bug in Response validator #40

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ronniel1
Copy link

Response validator replaces res.json with a custom function.
In case the user configured passError option, we need to restore the
original res.json function so that the error handling middleware can
update the response.

Response validator replaces res.json with a custom function.
In case the user configured passError option, we need to restore the
original res.json function so that the error handling middleware can
update the response.
Copy link

@itsikbelson-spotlight itsikbelson-spotlight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@ronniel1
Copy link
Author

Unfortunately this is not good enough.
If the request handler had an error, and calls next(err) instead of res.status(x).send(...) then res.json will not be restored, and then the error handling middleware will change the json the response validator will be invoked, and override the json response, which it shouldn't.

Any ideas how this can be resolved?

… when an error occures before the response is sent
@ronniel1
Copy link
Author

Added another commit that fixes the issue, in a hackish way.
The problem is how to cleanup the res.json patch when the response validator is not being called.
exported a function to cleanup the Response object, which can be called from the error handling middleware.

I don't really like this, but did not find another solution.

Copy link
Owner

@evanshortiss evanshortiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this PR! Can you take a look at the comments?

}
}

module.exports.fixupResponse = restoreResponseAfterResponseValidation
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be best not to expose this. Make the fix-up automatic in all scenarios, including response, if passError is enabled. WDYT?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see your last comment. Right, this is a tricky...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed Hacky. Do you have any other suggestion?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had this idea stewing in my head around providing schemas for certain status code ranges. It's a bit more complex though. Something like:

validation.response({
  // Schemas to run for given status codes
  '2xx': schemaSuccess,
  '4xx': schemaFail
}, {
  // These could be defined globally instead of as part of 
  // the call to response()
  passError: true
  passErrorSchemas: {
    '5xx': errrorHandlerSchema
  }
})

If no schema is provided for 5xx, then perhaps validation is bypassed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a very good interface.
It seems to me that it will still need the mechanism of overriding the json function on the Response object and require restoring the original json function

})
const res = getRequester(middleware, errorHandler)
.get('/error')
.expect(422)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a 500 error, yet the test is passing. That's odd. Checking res.statusCode in the end block instead will do the trick.

I'll need to look into why supertest is not asserting it correctly since it seems to be the same for other tests...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The errorHandler sets the status code to 422, so I think this works as expected

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

Successfully merging this pull request may close these issues.

3 participants