marshmallow-oneofschema
marshmallow-oneofschema copied to clipboard
Overriding `handle_error` does't work.
A custom exception can't be raised when has an error.
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,
)
)