如何在Python Pydantic中添加自定义字段验证并整合错误响应
解决Pydantic自定义验证错误未纳入422响应的问题
核心问题原因
直接抛出普通ValueError会被框架判定为未处理异常返回500,正确的做法是让自定义验证错误被Pydantic捕获,纳入其标准错误输出体系。
实现方案(Pydantic v2 + FastAPI)
直接在模型内通过@field_validator实现自定义验证,抛出Pydantic规范的错误:
from pydantic import BaseModel, field_validator, PydanticCustomError from uuid import UUID class ArtistInboundSearchModel(BaseModel): ids: str | None = None name: str | None = None @field_validator('ids', mode='before') def validate_comma_separated_uuids(cls, v): if v is None: return v # 分割ids字符串并逐个验证UUID格式 uuid_strings = v.split(',') for uuid_str in uuid_strings: stripped_uuid = uuid_str.strip() try: UUID(stripped_uuid) except ValueError: # 抛出Pydantic自定义错误,自动纳入422响应的错误列表 raise PydanticCustomError( 'invalid_uuid_list', 'ids必须是逗号分隔的有效UUID列表,无效值: {invalid_value}', {'invalid_value': stripped_uuid} ) return v
关键细节
mode='before'确保自定义验证在Pydantic默认类型校验前执行(因为ids定义为str,默认校验会先通过)- 抛出
PydanticCustomError而非普通ValueError,Pydantic会将该错误与其他字段的验证错误合并,统一返回422响应 - 错误信息包含自定义错误码、提示文本和无效值,完全贴合Pydantic标准错误格式
Pydantic v1兼容方案
如果仍在使用Pydantic v1,需构造ValidationError实例抛出:
from pydantic import BaseModel, validator, ValidationError, ErrorWrapper from uuid import UUID class ArtistInboundSearchModel(BaseModel): ids: str | None = None name: str | None = None @validator('ids') def validate_comma_separated_uuids(cls, v): if v is None: return v uuid_strings = v.split(',') for uuid_str in uuid_strings: stripped_uuid = uuid_str.strip() try: UUID(stripped_uuid) except ValueError: raise ValidationError([ ErrorWrapper( ValueError(f'ids必须是逗号分隔的有效UUID列表,无效值: {stripped_uuid}'), loc=('ids',) ) ]) return v
效果验证
当请求的ids参数包含无效值(比如ids=123,abc,550e8400-e29b-41d4-a716-446655440000)时,接口会返回422响应,错误列表中会显示自定义的UUID格式错误;如果name字段存在其他验证问题(比如长度不符合要求),也会一同被列出。
内容的提问来源于stack exchange,提问作者Clayton
相关产品推荐
相关产品推荐

