如何让Pydantic在校验失败时立刻抛出异常
前置修正
你现有代码存在笔误:第一个校验方法的入参名是email,但判断逻辑里用的变量是email_id,变量名不匹配会导致校验逻辑报错,需要先修正这个问题。
解决方案
Pydantic默认会收集全部校验错误后统一返回,要实现单字段校验失败立刻终止后续校验、直接抛出异常,按你使用的Pydantic版本选择对应方法即可:
1. Pydantic V1版本
给前置校验器添加skip_on_failure=True参数,该参数作用是当前校验抛出错误后,直接终止同字段后续的所有校验逻辑,立刻返回异常。
示例代码:
from pydantic import BaseModel, validator from typing import List class PayloadValidator(BaseModel): emailId: List[str] role: str @validator("emailId", skip_on_failure=True) def is_email_list_empty(cls, email_id): if not email_id: raise ValueError("Email list is empty.") return email_id @validator("emailId") def valid_domains(cls, emailId): # forbidden domain校验逻辑 invalid_domains = {"x.com", "y.com", "z.com"} for email in emailId: if '@' in email and email.split('@')[-1] in invalid_domains: raise ValueError(f"Email {email} uses forbidden domain.") return emailId
2. Pydantic V2版本
V2废弃了原有的validator装饰器,改用field_validator,同样添加skip_on_failure=True参数即可实现失败即停的效果。
示例代码:
from pydantic import BaseModel, field_validator from typing import List class PayloadValidator(BaseModel): emailId: List[str] role: str @field_validator("emailId", skip_on_failure=True) @classmethod def is_email_list_empty(cls, email_id): if not email_id: raise ValueError("Email list is empty.") return email_id @field_validator("emailId") @classmethod def valid_domains(cls, emailId): # forbidden domain校验逻辑 invalid_domains = {"x.com", "y.com", "z.com"} for email in emailId: if '@' in email and email.split('@')[-1] in invalid_domains: raise ValueError(f"Email {email} uses forbidden domain.") return emailId
补充说明
如果你需要全局所有校验都实现失败即停,可以在模型配置里添加全局参数:
- V1版本:在模型内新增
class Config: validate_all = False - V2版本:在模型内新增
model_config = {"skip_on_failure": True}
更推荐只给需要提前终止的字段校验器加单独参数,避免影响其他不需要提前终止的校验逻辑。
内容的提问来源于stack exchange,提问作者Jeet Patel
相关产品推荐
相关产品推荐

