formik: `validate` swallows Exceptions

🐛 Bug report

Current Behavior

Formik’s validate handler swallow all exceptions, silently.

<Formik
  validate={validate}
/>

function validate() {
  throw new Error("Oooops, s*** went wrong");
}

Expected behavior

Error should be displayed in console

Reproducible example

Codesandbox example here https://codesandbox.io/s/xvn1nw30vw

Observations

  • looks like behaviour changed. The issue is, if validation is async, Formik awaits for it in try/catch block. Maybe we should expose FormikValidationException which would accept validation errors and check for this exception in mentioned try/catch block.

Solutions proposal

New API

  • Introduce FormikValidationException which is… exceptional 👏
  • update Formik’s validation handler to check exception type thrown in try/catch block

Usage example

import { Formik, FormikValidationException } from 'formik';

function validate(values) {
  const { valid, errors } = someValidator(values);
  if (!valid) {
    throw new FormikValidationException(errors)
  }
}

<Formik validate={validate}>
   {/* children */}
</Formik>

Change existing behavior

  • skip try/catch block
  • consider resolved value as validation errors

Usage example

import { Formik } from 'formik';

function validate(values) {
  const errors = {};
  if (!values.email) {
    errors.email = 'validation message';
  }
  return errors;
}

<Formik validate={validate}>
   {/* children */}
</Formik>

Your environment

Software Version(s)
Formik 1.5.0
React 16.8

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 18
  • Comments: 17 (1 by maintainers)

Most upvoted comments

Any updates on this?

Agree. I think we should fix this in v2.

– Jared


From: Andrej Badin notifications@github.com Sent: Thursday, May 9, 2019 7:31 PM To: jaredpalmer/formik Cc: Jared Palmer; Mention Subject: Re: [jaredpalmer/formik] validate swallows Exceptions (#1329)

@jaredpalmerhttps://github.com/jaredpalmer I am testing v2-alpha in some of my projects and I see validate expects to throw errors, which is de facto original behaviour. Are you considering a change here? To be precise, returning/expecting resolved errors bag, instead of awaiting Promise rejection?

This could be real pain point when even errors in validation process itself are swallowed (typo, invalid validator, etc.) and hard to discover for many users.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/jaredpalmer/formik/issues/1329#issuecomment-491102811, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AA67IG6FR6KCYESR4DWN22DPUSX47ANCNFSM4GXI6D3A.

Yup. I think to resolve instead of to throw is correct approach

To me it seems like we should at least be getting the console.warn of the actualException. Is this really an issue with Formik or is it a side effect of React Memo? Because in a standalone promise we would surely see the warning with the actual exception. And I would suggest it is not typical to throw errors inside of a Promise function but rather to send it w/reject inside the promise. And yes my NODE_ENV is set to ‘development’ which is why I ask my question.

@jaredpalmer I am testing v2-alpha in some of my projects and I see validate expects to throw errors, which is de facto original behaviour. Are you considering a change here? To be precise, returning/expecting resolved errors bag, instead of awaiting Promise rejection?

This could be real pain point when even errors in validation process itself are swallowed (typo, invalid validator, etc.) and hard to discover for many users.

If you are not willing to change this behaviour, at least let’s introduce deterministic API, e.g. throwing custom ValidationException with validation errors and detect exception in handler.