Search code examples
pythonflaskmarshmallowflask-restplus

marshmallow ValidationError not handled correctly by flask error handler


I don't know if this matters, but I'm actually using flask-restplus extension.

All of my other flask error handlers work as expected, but for some reason when handling a marshmallow ValidationError, the response is just my original request body, instead of the marshmallow error message. I've done some debugging and I know that the error handler is being called, and that attributes of the ValidationError are accessible (e.g. verified that error.messages is {'age': ['Missing data for required field.']}).

Has anyone experienced this before? Thanks for reading, and thanks in advance for any help!

The payload:

{"name": "Bob"}

The error handler:

from marshmallow.exceptions import ValidationError

@api.errorhandler(ValidationError)
def marshmallow_error_handler(error):
    # print(error.messages) results in expected {'age': ['Missing data for required field.']}
    return error.messages, 400

The schema:

class SimpleSchema(Schema):
    name = fields.String(required=True)
    age = fields.String(required=True)

Simple route to test handler:

@api.route("/test")
class MarshmallowTest(Resource):
    def post(self):
        SimpleSchema().load(api.payload)

Expected response:

{'age': ['Missing data for required field.']}

Actual response:

{"name": "Bob"}

I've been able to work around this by overriding marshmallow.Schema's handle_error function and raising a custom exception, but I'm still quite curious what's causing this behavior!


Solution

  • I ran into this error as well and found this Github issue https://github.com/noirbizarre/flask-restplus/issues/530

    The workaround I went with is overwriting the data property of the exception in my own handler

        @api.errorhandler(Exception)
        def handle_unexpected_within_restx(e):
            app.logger.exception(e)
            
            data = compose_error_response(e.messages)
            # https://github.com/noirbizarre/flask-restplus/issues/530
            e.data = data
            return data, 400