keleshev / schema

Schema validation just got Pythonic
MIT License
2.87k stars 215 forks source link

user-friendly error-message is ignored #158

Open marioschaefer opened 6 years ago

marioschaefer commented 6 years ago

Hi,

i have a case where a custom-error-message is ignored:

    reports = ["asdf", "aaa", "bbb"]
    validsatype = ['root', 'vsys', 'vsa']
    customerschema = Schema({'name': str,
                             Optional('satype'): And(str, Use(str.lower), lambda s: s in validsatype,
                                                     error="Invalid satype. Valid: %s" % (', '.join(validsatype))),
                             'reports': {
                                 And(str, Use(str.lower), lambda s: s in reports, error="invalid reportname. Valid: %s" % (', '.join(reports))): {}
                             }
                             }, ignore_extra_keys=True)
    customer = {"name": "customer1",
                        "satype": "root",
                        "reports": {"asdf": {"schedule": {"duration": "last1m",}}}}
    try:
        customer = customerschema.validate(customer)
    except SchemaError as exc:
        logger.error("%s: config-Schemavalidation failed: %s" % (customer['name'], exc.code))
    except:
        logger.exception("%s: config-Schemavalidation failed, unknown exception" % customer['name'])

But Output is without the custom-error: config-Schemavalidation failed: Missing keys: And(<class 'str'>, Use(<method 'lower' of 'str' objects>), <function customercheck.<locals>.<lambda> at 0x00000230300EB048>) BaseException

But its working for the "satype"-check, i cant really see any difference in the schema. Any difference: satype is a value while reports is a key

some-0n3 commented 5 years ago

I'm not 100% sure exactly what you want, but it might be this::


customerschema = Schema({
    'name': str,
    Optional('satype'): And(
        str, Use(str.lower), lambda s: s in validsatype,
        error="Invalid satype. Valid: %s" % (', '.join(validsatype))),
    'reports': Schema({
        And(str, Use(str.lower), lambda s: s in reports) : {}
    }, error="invalid reportname. Valid: %s" % (', '.join(reports)))
}, ignore_extra_keys=True)
...```