Error Handling
This guide focuses on using ValidasiResult<T> effectively when validation fails.
What You Get from ValidasiResult
Every validation returns:
isValid: validation statusdata: validated/transformed value (when valid)errors: list ofValidationError
Each ValidationError contains:
rule: rule name that produced the errormessage: human-readable error messagepath: field path for nested valuesdetails: optional debug metadata
Basic Error Flow
dart
final result = schema.validate(input);
if (result.isValid) {
useValidatedData(result.data);
return;
}
for (final error in result.errors) {
final path = error.path?.join('.') ?? 'root';
print('[$path] ${error.message} (${error.rule})');
}Use this as your default pattern:
- Check
isValid. - On failure, iterate
errors. - Use
pathfor field mapping andrule/detailsfor debugging.
Full Use of ValidationError Fields
dart
for (final error in result.errors) {
final field = error.path?.join('.') ?? 'root';
final rule = error.rule;
final message = error.message;
final debug = error.details;
print('field=$field rule=$rule message=$message details=$debug');
}messageis for user feedback.pathis for attaching errors to inputs.ruleanddetailsare for logs and diagnostics.
Convert Errors for UI
dart
Map<String, List<String>> errorsByField<T>(ValidasiResult<T> result) {
final grouped = <String, List<String>>{};
for (final error in result.errors) {
final field = error.path?.join('.') ?? 'root';
grouped.putIfAbsent(field, () => []).add(error.message);
}
return grouped;
}This makes it easy to show per-field errors in forms.
Convert Errors for API Responses
dart
List<Map<String, dynamic>> errorsToJson<T>(ValidasiResult<T> result) {
return result.errors
.map((error) => {
'field': error.path?.join('.'),
'rule': error.rule,
'message': error.message,
'details': error.details,
})
.toList();
}Throwing Validation Errors
dart
class ValidationException implements Exception {
ValidationException(this.errors);
final List<ValidationError> errors;
@override
String toString() {
return errors
.map((e) => '[${e.path?.join('.') ?? 'root'}] ${e.message}')
.join(', ');
}
}
void save(dynamic payload) {
final result = schema.validate(payload);
if (!result.isValid) {
throw ValidationException(result.errors);
}
persist(result.data);
}Best Practices
- Always branch on
result.isValidfirst. - Use
error.pathas the source of truth for field-level mapping. - Keep user messages in
message; keep diagnostics in logs withruleanddetails. - Return full
errorsin internal layers, then format at the boundary (UI/API).
