marshmallow-oneofschema icon indicating copy to clipboard operation
marshmallow-oneofschema copied to clipboard

Overriding `handle_error` does't work.

Open jairhenrique opened this issue 5 years ago • 1 comments

A custom exception can't be raised when has an error.

jairhenrique avatar Apr 26 '19 19:04 jairhenrique

I also ran into this issue in case the requestor specified an invalid type.

To work around this I created a new type_schema which was based on the type_field (unfortunately adding code duplication), and achieved my desired results of a custom handle_error

Example using invalid_grant as the type_schema failure:

# ... imports here - removed for example
from marshmallow import Schema

class HandleValidationException(Schema):
    def handle_error(self, error, data, *, many, **kwargs):
         # ... custom error handling code here - removed for example
         pass
       
class GrantTypeClientCredentialsSchema(Schema, HandleValidationException):
    # ... code here - removed for example
     pass

class GrantTypePasswordSchema(Schema, HandleValidationException)
    # ... code here - removed for example
     pass

class InvalidGrantSchema(Schema, HandleValidationException):
    GRANT_TYPE_PROPERTY = 'grant_type'
    GRANT_TYPE_EXAMPLE = GrantType.USERNAME_PASSWORD
    GRANT_TYPE_DESC = 'Grant type'
    GRANT_TYPE_TITLE = 'Grant Type'

    grant_type = EnumField(
        GrantType,
        load_only=True,
        required=True,
        by_value=True,
        validate=validate.OneOf(GrantType),
        metadata=dict(
            title=GRANT_TYPE_TITLE,
            description=GRANT_TYPE_DESC,
            example=GRANT_TYPE_EXAMPLE,
        )
    )


class TokenRequestSchema(OneOfSchema, HandleValidationException):

    GRANT_TYPE_PROPERTY = 'grant_type'
    GRANT_TYPE_EXAMPLE = GrantType.USERNAME_PASSWORD
    GRANT_TYPE_DESC = 'Grant type'
    GRANT_TYPE_TITLE = 'Grant Type'

    # Part of the OneOf schema logic
    # Bug in OneOfSchema: 'handle_error' is not honored,
    # so workaround to have separate schema for error case of grant type
    #  - https://github.com/marshmallow-code/marshmallow-oneofschema/issues/74
    type_schemas = {
        GrantType.CLIENT_CREDENTIALS.value: GrantTypeClientCredentialsSchema,
        GrantType.USERNAME_PASSWORD.value: GrantTypePasswordSchema,
        'invalid_grant': InvalidGrantSchema,
    }
    type_field = GRANT_TYPE_PROPERTY
    type_field_remove = False

    grant_type = EnumField(
        GrantType,
        load_only=True,
        required=True,
        by_value=True,
        validate=validate.OneOf(GrantType),
        metadata=dict(
            title=GRANT_TYPE_TITLE,
            description=GRANT_TYPE_DESC,
            example=GRANT_TYPE_EXAMPLE,
        )
    )

arthurvanduynhoven avatar Aug 25 '22 06:08 arthurvanduynhoven