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

HTTP status code 400 vs 422 #180

Closed
dwoz opened this issue Jul 18, 2017 · 12 comments

Comments

@dwoz
Copy link

commented Jul 18, 2017

I'm wondering if someone can explain why webargs is responding with a 422 status code for missing form arguments. I was expecting a 422 (Unproccessable Entity) status when JSON fails to parse but 400 for a missing argument.

stack overflow 400 vs 422
https://httpstatuses.com/422

@sloria

This comment has been minimized.

Copy link
Member

commented Jul 19, 2017

The server understands the content type of the request entity (hence a 415 Unsupported Media Type status code is inappropriate), and the syntax of the request entity is correct (thus a 400 Bad Request status code is inappropriate) but was unable to process the contained instructions.

422 is an appropriate status code for missing arguments; the media type (form data) and syntax are correct (i.e. the form data are syntactically correct, if not semantically correct).

I went back-and-forth between 400 vs 422 a number of times, and I understand you could argue for either. IIRC, I settled on 422 for all validation errors because there were good examples in the wild (e.g. GitHub's API) that did so.

@dwoz

This comment has been minimized.

Copy link
Author

commented Jul 27, 2017

@sloria Yep, re-reading everything myself I agree 422 is the proper response. Thanks for looking into this again.

@dwoz dwoz closed this Jul 27, 2017

@foresmac

This comment has been minimized.

Copy link

commented Jun 5, 2018

I'd like to revisit this issue, if at least to determine a way to override the default 422 and replace with 400. Every RESTful API I've ever created or used uses 400 for input validation failures. The only way I can think of to do this now is some very hack-y monkey-patching.

@foresmac

This comment has been minimized.

Copy link

commented Jun 5, 2018

We have a mix of web services written in Django/DRF, Golang, and falcon. We have been using basically manual input validation in certain critical paths until we could settle on a validation strategy. Our organization decided to adopt webargs, but we may have to revisit that if all the falcon services are going to return a 422 while everything else uses 400.

@sloria

This comment has been minimized.

Copy link
Member

commented Jun 5, 2018

@foresmac You can override the default status code on the Parser class.

from webargs.falconparser import FalconParser

class Parser(FalconParser):
    DEFAULT_VALIDATION_STATUS = 400


parser = Parser()

Does this meet your use case?

@foresmac

This comment has been minimized.

Copy link

commented Jun 5, 2018

@sloria Hrmmmm, would I then use @parser.use_args as the decorator?

@foresmac

This comment has been minimized.

Copy link

commented Jun 5, 2018

I tried the above and I'm still getting 422 responses for failed validation.

@foresmac

This comment has been minimized.

Copy link

commented Jun 5, 2018

It looks like the Parser subclass never passes self.DEFAULT_VALIDATION_STATUS to ValidationError constructors, so it uses the value of the constant defined earlier in the file, which is 422.

@foresmac

This comment has been minimized.

Copy link

commented Jun 5, 2018

I was able to achieve the result by doing something like the following:

import falcon

from webargs.falconparser import FalconParser, HTTPError


class AnalyteParser(FalconParser):
    DEFAULT_VALIDATION_STATUS = 400

    def handle_error(self, error, req):
        """Handles errors during parsing."""
        raise HTTPError(falcon.HTTP_BAD_REQUEST, errors=error.messages)


parser = AnalyteParser()
@sloria

This comment has been minimized.

Copy link
Member

commented Jun 6, 2018

Ah, that works. However, it looks like you found a bug: Parser.DEFAULT_VALIDATION_STATUS is unused. I'll look into a patch for this soon.

sloria added a commit that referenced this issue Jun 6, 2018

@sloria

This comment has been minimized.

Copy link
Member

commented Jun 7, 2018

@foresmac The issue with DEFAULT_VALIDATION_STATUS is fixed in 3.0.1 and is documented here: https://webargs.readthedocs.io/en/latest/advanced.html#returning-http-400-responses

@alessandromarchetti

This comment has been minimized.

Copy link

commented Jul 17, 2019

I'm using version 5.3.1 and the returned error code can also be set directly in use_args/use_kwargs decorator methods of the default falconparser, e.g. @use_args(args, error_status_code=400). I thought it might be useful for who lands in this thread, if it doesn't please delete it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.