Preferred method for handling pydantic validation errors?
See original GitHub issueLet’s say I have the following code and the reponse from google is invalid when being loaded into the GoogleTokenValidationResponse
schema.
import requests
from ninja.errors import ValidationError
class GoogleTokenValidationResponse(Schema):
iss: str
nbf: str
au: str
sub: str
def validate_google_credential(id_token: str):
response = requests.get(
"https://oauth2url.com, params={"id_token": id_token}
)
if not response.ok:
raise ValidationError("id_token is invalid.")
response_data = GoogleTokenValidationResponse(**response.json())
return response_data
The result is a 500
error with a traceback like so:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/ninja/operation.py", line 99, in run
result = self.view_func(request, **values)
File "/opt/app/api/authentication/views.py", line 23, in login
google_response_data = validate_google_credential(
File "/opt/app/api/authentication/helpers.py", line 96, in validate_google_credential
response_data = GoogleTokenValidationResponse(**response.json())
File "/usr/local/lib/python3.10/site-packages/pydantic/main.py", line 342, in __init__
raise validation_error
pydantic.error_wrappers.ValidationError: 1 validation error for GoogleTokenValidationResponse
au
field required (type=value_error.missing)
I’d like to handle this error more elegantly, so I tried catching the Pydantic validation error like so:
import requests
from ninja.errors import ValidationError
from pydantic import ValidationError as PydanticValidationError
def validate_google_credential(id_token: str):
response = requests.get(
GoogleOauth.TOKEN_INFO_URL.value, params={"id_token": id_token}
)
if not response.ok:
raise ValidationError("id_token is invalid.")
try:
response_data = GoogleTokenValidationResponse(**response.json())
except PydanticValidationError:
raise ValidationError("Google response was malformed.")
return response_data
which gives me a nice 422
error with {"detail": "Google response was malformed."}
I like how this functions, but I’m not too keen on the idea of putting every schema load in to a try/except.
Is there any clean method to catch all pydantic
validation errors and handle them so they return 422
errors with a clean error instead of a traceback? I’m not too concerned about the specificity of message, something generic like “error validating data” would be fine, but it would be nice to bee able to hook in something more specific,
Issue Analytics
- State:
- Created 9 months ago
- Comments:5 (3 by maintainers)
Thanks for that very detailed response! It’s quite helpful for me.
Without knowing anything about the use case of your endpoint or the oauth service you’re using, I can’t give particuarly detailed advice.
My understanding is, you’ve got a function that takes in a token value from the client, sends it to google to validate it, and google sends back data that either you or the client need to perform further actions. These are the possible outputs I see from this process:
As for exactly what your response contains beyond the error code, that’s pretty use case dependent. If the response is going to something that end users interact with directly (e.g. website or app) then I’d generally return some text that the user can understand. You’d want to make it clear where the error is e.g. “token_id is not a valid token” rather than just “validation error”. If the response is going to just be read by other people’s software, then it can be less user friendly.
Showing a traceback is never a good idea unless you’re the only person that’s going to be seeing the responses. At best people won’t understand it, at worst it’ll reveal a vunerablility in your code.