question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ValidationError causes HTTP/500 in Flask instead of HTTP/422 in Python 2

See original GitHub issue

Here are the symptoms: http://stackoverflow.com/questions/37321835/flask-error-handler-not-able-to-handle-assertion-error/39624893#39624893

Here is the case where I personally hit the issue with Python 2.x and PyPy in Python 2.x mode only: https://travis-ci.org/frol/flask-restplus-server-example/builds/161685419

After troubleshooting, I discovered that this issue stems from the FlaskParser.handle_error which calls abort function with exc= argument, which then is set as “data” on the raised HTTPException, which in its turn is tried to be json-dumped and fails with TypeError, and now the new exception is in sys.exc_info(), which causes Flask to assert here.

Searching git history for the introduced exc= in FlaskParser, I found it here: https://github.com/sloria/webargs/commit/6f8088c7c85c05d2891e81ee97d38f2ae801159d

Is there a reason for exc= to be passed? How can we fix this?

Python 3 seems to have changed something with sys.exc_info() behaviour since even after the TypeError caused by json.dumps(), sys.exc_info() still reports HTTPException while in Python 2 it returns TypeError.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
frolcommented, Oct 13, 2016

I took the option 1 in my project: https://github.com/frol/flask-restplus-server-example/blob/8118f66e3c9c505da1b92f3373c4b3c583af3bf6/app/extensions/api/webargs_parser.py

I am not sure how this can be handled in a better way, so if you happen to find a better solution, please, share.

1reaction
frolcommented, Oct 13, 2016

Here is what happened before my fix:

  1. Request is received
  2. Webargs parsing it in FlaskParser
  3. If validation failed, handle_error is called
  4. handle_error called abort(status_code, messages=error.messages, exc=error)
  5. abort patches the HTTPException passing all **kwargs (messages and exc) to HTTPException.data
  6. Flask-RESTful gets this data, and tries to serialize it to JSON
  7. json.dumps fails because it cannot serialize exc object passed through abort (steps 4-5)
  8. Flask-RESTful catches JSON-Encode-Error (TypeError) and passes this handling to your app.error_handler, and here the Python 2 and Python 3 difference jumps in, Python 3 has the long story of exceptions and the original exception was HTTPException/422, but Python 2 overrides this info with the latest JSON-Encode-Error (TypeError) and, as a result, you have HTTP/500.

In any case, Webargs abort implementation didn’t work, it led to the JSON-Encode-Error exception which was handled expectedly on Python 3 only by a pure luck.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Flask error handler not able to handle Assertion Error
I see this issue only with Python 2.7 while Python 3.3, 3.4, 3.5 work fine. Thus, I think it should be considered as...
Read more >
Handling Application Errors — Flask Documentation (2.2.x)
When an error occurs in Flask, an appropriate HTTP status code will be returned. ... 500-599 indicate errors with the server or application...
Read more >
webargs(1) - Arch manual pages
webargs is a Python library for parsing and validating HTTP request objects, with built-in support for popular web frameworks, including Flask, Django, ...
Read more >
422 Unprocessable Entity - HTTP - MDN Web Docs
The HyperText Transfer Protocol (HTTP) 422 Unprocessable Entity response status code indicates that the server understands the content type ...
Read more >
How To Fix the HTTP 422 Error - Kinsta
Broadly speaking, if you see an HTTP 422 error it means the server understands your request, but it can't fulfill it due to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found