The RequestValidationError mostly shouldn't happen unless we've made a programming error (mismatch between the frontend form and the backend Pydantic request model). If it does happen, we are rendering the "validation_error.html" file.
The PasswordValidationError is a bit more mission critical, because users may occasionally encounter this, and we want the logic to be re-usable for validation of inputs to other forms. As much as possible in all such cases, we should prevent invalid inputs with HTML and Javascript pattern-matching on the frontend so that users don't reach "validation_error.html".
Previously I was manually handling this validation in the body of the API endpoint. Now I am handling validation with a Pydantic-powered dependency in the function signature. I like how this separates concerns, and it allows me to handle the redirect behavior centrally from middleware.
In the previous version, I was redirecting back to the page with an error toast. The good thing about that pattern is that the user doesn't have to navigate back to the page. The bad thing is that it clears the form data and doesn't separate out validation from other concerns. Now I am rendering a separate error page, "validation_error.html". The disadvantage of this is that the user has to click "Go Back" to return to the page and try again. The advantage is that this back-navigation preserves the user's form inputs.
I experimented with some approaches to using error toasts in a way that would preserve form data. It's possible, but unfortunately you can't pass context in a redirect. If you are redirecting from the body of the API endpoint, you could pass the form inputs as query parameters. But this will expose the user's password inputs in the URL, which is bad. And you can't use this approach from our Pydantic field validators anyway. A better approach would be to use session middleware to get the form data from the session request object. But that requires an additional dependency, so I skipped it for now.
Design notes for this version:
The
RequestValidationError
mostly shouldn't happen unless we've made a programming error (mismatch between the frontend form and the backend Pydantic request model). If it does happen, we are rendering the "validation_error.html" file.The
PasswordValidationError
is a bit more mission critical, because users may occasionally encounter this, and we want the logic to be re-usable for validation of inputs to other forms. As much as possible in all such cases, we should prevent invalid inputs with HTML and Javascript pattern-matching on the frontend so that users don't reach "validation_error.html".Previously I was manually handling this validation in the body of the API endpoint. Now I am handling validation with a Pydantic-powered dependency in the function signature. I like how this separates concerns, and it allows me to handle the redirect behavior centrally from middleware.
In the previous version, I was redirecting back to the page with an error toast. The good thing about that pattern is that the user doesn't have to navigate back to the page. The bad thing is that it clears the form data and doesn't separate out validation from other concerns. Now I am rendering a separate error page, "validation_error.html". The disadvantage of this is that the user has to click "Go Back" to return to the page and try again. The advantage is that this back-navigation preserves the user's form inputs.
I experimented with some approaches to using error toasts in a way that would preserve form data. It's possible, but unfortunately you can't pass context in a redirect. If you are redirecting from the body of the API endpoint, you could pass the form inputs as query parameters. But this will expose the user's password inputs in the URL, which is bad. And you can't use this approach from our Pydantic field validators anyway. A better approach would be to use session middleware to get the form data from the session request object. But that requires an additional dependency, so I skipped it for now.