4 · Errors
The unique selling point. Every other library on the JVM/Rust/Python market fails fast. iron-monk does not.
Why
When a payload has three bad fields, your user wants to know all three at once, not one at a time as they fix each. Aggregation is the difference between a usable API and a frustrating one.
How
A failed validation raises a single ValidationError carrying a list of ErrorDict:
from monk import validate
from monk.exceptions import ValidationError
try:
validate(User(email="bad-email", age=12))
except ValidationError as e:
print(len(e.errors)) # 2 — both email and age are reported
print(e.errors[0]) # {"field": "email", "message": "...", "code": "Email"}
print(e.flatten()) # ["email: Must be a valid email address.", "age: ..."]
print(e.to_rfc7807()) # RFC 7807 problem-detail dict for HTTP APIs
Each ErrorDict carries:
field— dotted path to the offending field. Nested fields look likeaddress.zip; list items liketags[2]; dict values likeprefs['theme'].message— human-readable, overridable per-constraint withmessage=....code— stable machine-readable identifier (the constraint class name by default, or a customcode=...).
Gotchas
- Standalone
Constraint.validate()is not aggregated. It raises nativeValueError/TypeErrorbecause there is no field context to aggregate over. Aggregation is a property ofvalidate/validate_value/validate_dict/ function-mode@monk. to_rfc7807()defaults to HTTP 400. Passstatus=,title=,type_uri=,instance=to customize per route.- Error codes are class names by default. If you alias a constraint (
MyEmail = Email), the code stays"Email". To override, setcode="..."on the constraint instance.
Next Steps
- Constraints Toolkit — every built-in constraint with examples.
- Cross-Field Validation —
Refand the__monk_validate__hook. - Customization — defining your own constraints in three lines.
- Settings & Type Metadata — unwrappers, type-keyed metadata, env vars for framework integration.