Skip to content

Error Handling

zod-rs provides detailed error information with full path tracking for nested structures.

use zod_rs::prelude::*;
use serde_json::json;
let schema = string().email();
match schema.safe_parse(&json!("not-an-email")) {
Ok(value) => println!("Valid: {}", value),
Err(errors) => println!("Invalid: {}", errors),
}

Errors in nested objects include the full field path:

let schema = object()
.field("user", object()
.field("name", string().min(2))
.field("email", string().email())
);
let data = json!({
"user": {
"name": "A",
"email": "invalid-email"
}
});
match schema.safe_parse(&data) {
Err(errors) => {
println!("{}", errors);
// Output:
// - user.name: Too big: expected string to have >= 2 characters
// - user.email: Invalid email address
}
_ => {}
}
ErrorDescription
ValidationError::RequiredMissing required field
ValidationError::InvalidTypeWrong data type
ValidationError::InvalidValueValue doesn’t match expected value
ValidationError::InvalidValuesValue doesn’t match any expected values
ValidationError::TooSmallValue or length below minimum
ValidationError::TooBigValue or length above maximum
ValidationError::InvalidFormatString format validation failed (starts_with, ends_with, includes, regex)
ValidationError::InvalidNumberNumber constraint failed (finite, positive, etc.)
ValidationError::UnrecognizedKeysObject has unrecognized keys (strict mode)
ValidationError::InvalidUnionNo union variant matched
ValidationError::CustomCustom validation error
match schema.safe_parse(&data) {
Err(validation_result) => {
for issue in &validation_result.issues {
println!("Error: {}", issue);
}
}
_ => {}
}

Implement the Schema trait for custom validation logic:

use zod_rs::prelude::*;
use zod_rs_util::{ValidationError, ValidateResult};
use serde_json::Value;
struct MinWords {
min: usize,
}
impl Schema<String> for MinWords {
fn validate(&self, value: &Value) -> ValidateResult<String> {
let s = value.as_str()
.ok_or_else(|| ValidationError::invalid_type("string", "other"))?
.to_string();
let word_count = s.split_whitespace().count();
if word_count < self.min {
return Err(ValidationError::custom(
format!("Must contain at least {} words", self.min)
).into());
}
Ok(s)
}
}
let schema = MinWords { min: 3 };
assert!(schema.safe_parse(&json!("hello world rust")).is_ok());
assert!(schema.safe_parse(&json!("hello")).is_err());