-
-
Notifications
You must be signed in to change notification settings - Fork 468
Docs: Add error handling section to submission handling docs #1566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
LeCarbonator
wants to merge
5
commits into
TanStack:main
Choose a base branch
from
LeCarbonator:docs-submission-handling
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
f186229
docs: expand submission handling in react
LeCarbonator 19196cd
docs: expand submission handling in solid
LeCarbonator 3b47efe
docs: expand submission handling in vue
LeCarbonator 835d6c6
docs: fix validation hyperlink
LeCarbonator 9cc5382
docs: apply suggestions to submission-handling.md
LeCarbonator File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -3,6 +3,83 @@ id: submission-handling | |||||||||||||
title: Submission handling | ||||||||||||||
--- | ||||||||||||||
|
||||||||||||||
## Error handling | ||||||||||||||
|
||||||||||||||
When a user submits a form, there are several ways errors can occur — each requiring its own handling approach. TanStack Form gives you the flexibility to handle errors your way. To help you get started, here’s how to approach the three most common types of errors you’ll run into: | ||||||||||||||
|
||||||||||||||
- **Synchronous user errors** – Things you can catch right away, like a field being left empty or text that's too short. | ||||||||||||||
- **Asynchronous user errors** – Issues that come up after submission, like finding out a username is already taken. | ||||||||||||||
- **Server errors** – Unexpected problems on the backend, such as a failed request or an unknown error. | ||||||||||||||
|
||||||||||||||
> [!TIP] | ||||||||||||||
> If you need help understanding how validation works in TanStack Form, be sure to check out the [form validation](./validation.md) guide! | ||||||||||||||
|
||||||||||||||
### Synchronous user errors | ||||||||||||||
|
||||||||||||||
These are validation issues that can be detected immediately on the client side, even before the form is submitted. They are typically managed using both form-level and field-level validators, as shown in the example below: | ||||||||||||||
|
||||||||||||||
```tsx | ||||||||||||||
<form.Field | ||||||||||||||
name="age" | ||||||||||||||
validators={{ | ||||||||||||||
onChange: ({ value }) => | ||||||||||||||
value < 13 ? 'You must be 13 to make an account' : undefined, | ||||||||||||||
}} | ||||||||||||||
children={{() => <>{/* ... */}</>}} | ||||||||||||||
/> | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
### Asynchronous user errors | ||||||||||||||
|
||||||||||||||
Asynchronous errors usually occur after the form is submitted, often due to external checks — like verifying whether a username or email is already taken. These kinds of errors can be handled using the async variants of form and field validators. | ||||||||||||||
|
||||||||||||||
Since these requests are usually at form level, see how you can [set field-level errors from the form's validators](./validation.md). | ||||||||||||||
|
||||||||||||||
```tsx | ||||||||||||||
const form = useForm({ | ||||||||||||||
// ... | ||||||||||||||
validators: { | ||||||||||||||
onSubmitAsync: async ({ value }) => { | ||||||||||||||
// Validate the value on the server | ||||||||||||||
const response = await createAccount(value) | ||||||||||||||
|
||||||||||||||
if (response.isError) { | ||||||||||||||
// Username is taken, return an error for the username field | ||||||||||||||
return { | ||||||||||||||
LeCarbonator marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
fields: { | ||||||||||||||
username: response.message, | ||||||||||||||
}, | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
// The account creation was a success. There is no error that needs to be shown. | ||||||||||||||
return null | ||||||||||||||
}, | ||||||||||||||
}, | ||||||||||||||
}) | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
### Server errors | ||||||||||||||
|
||||||||||||||
Server errors are unexpected failures that happen during submission — like connectivity issues or internal server faults. These aren't related to user input and therefore **should not be part of form validation**. | ||||||||||||||
|
||||||||||||||
These kinds of errors are typically handled by an external library, such as `TanStack Query`: | ||||||||||||||
|
||||||||||||||
```tsx | ||||||||||||||
// Using TanStack Query for data mutations | ||||||||||||||
const createAccountMutation = useMutation({ | ||||||||||||||
/* ... */ | ||||||||||||||
}) | ||||||||||||||
|
||||||||||||||
const form = useForm({ | ||||||||||||||
// ... | ||||||||||||||
onSubmit: async ({ value }) => { | ||||||||||||||
// If an error happens, they are accessible through | ||||||||||||||
// `createAccountMutation.error` | ||||||||||||||
await createAccountMutation.mutateAsync(value) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Promoting "mutateAsync" here feels off:
Suggested change
|
||||||||||||||
}, | ||||||||||||||
}) | ||||||||||||||
``` | ||||||||||||||
|
||||||||||||||
## Passing additional data to submission handling | ||||||||||||||
|
||||||||||||||
You may have multiple types of submission behaviour, for example, going back to another page or staying on the form. | ||||||||||||||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.