Skip to content

[v2] Standardize exception handling during submission #2306

Description

@LeCarbonator

Calling form.handleSubmit() can run several phases: field validation, form validation, and onSubmit. Any of these phases may throw because of an application error. With onSubmitInvalid being added, submission failures need consistent behavior regardless of where they originate.

Normal validation failures should remain distinguishable from unexpected exceptions, and the behavior of form.handleSubmit() should not depend on which submission phase failed.

Planned for behaviour

  • Call onSubmitInvalid for exceptions from field validation, form validation, and onSubmit, in addition to reported validation issues.
  • Pass a cause to onSubmitInvalid that identifies the failing phase, such as "field_validation" | "form_validation" | "on_submit".
  • Do not catch exceptions thrown by onSubmitInvalid. This allows consumers to throw deliberately when they want the rejected promise to reach an error screen or other error boundary.
  • Determine the rejection of the form.handleSubmit() promise before invoking onSubmitInvalid, so the callback cannot change whether the original submission error rejects.

Validation results should still be inspectable separately from exceptions:

// `cause` === `"field_validator" | "form_validator"`
const { errors, cause } = await form
  .handleSubmit()
  .catch(() => 'real error thrown')
const isInvalid = errors.length > 0

Some thoughts

The exact cause discriminator names still need to be made consistent. The proposed behavior uses the same categories regardless of whether they are ultimately named field_validation and form_validation or field_validator and form_validator.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: typesThis issue affects the types of the library.scope: coreThis issue affects the core package, meaning any adapter is also affected by it.v2This issue affects v2 as well.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions