sveltekit-superforms icon indicating copy to clipboard operation
sveltekit-superforms copied to clipboard

better server error handling

Open macmillen opened this issue 1 year ago • 3 comments

Is your feature request related to a problem? Please describe. Currently the handling of server side errors is a big pain. Our situation is that we have server errors like these:

  let errors = [
    {
      path: "settings.stripe.testSignatureKey",
      messages: ["Wrong API key"],
    },
  ];

and we want to automatically set form errors based on these server errors.

We can't do this:

superForm.errors.update((errors) => ({
  ...errors,
  newError,
}))

because the errors vanish as soon as someone modifies an input field.

I also tested other hacky solutions like this one with a recursive refine that checks for errors in the error store that match with a field of the zod schema:

const refineAllPaths = (
  validators: ZodValidation<AnyZodObject>,
  paths: string[] = zodKeys(validators),
): ZodValidation<AnyZodObject> => {
  if (paths.length === 0) return validators;

  const [path, ...restPaths] = paths;

  return refineAllPaths(
    validators.refine(
      () => {
        const errors = get(serverErrorStore);
        const error = errors.find((error) => error.path === path);
        if (error) {
          console.log("error found", error);
          return false;
        }
        return true;
      },
      () => ({
        message: "Error",
        path: path!.split("."),
      }),
    ),
    restPaths,
  );
};

But here we have a separate errorStore where we store all server errors after submit but like that we have race conditions because refine runs before the errors are set. and it generally feels really hacky.

  • we have to use client side validation because we are using GraphQL and we currently can't update the cache with the data of the server

Describe the solution you'd like It would be really nice if we had a nice way to let superforms handle these things natively or provide a way to make the manually set errors not vanish on form modifications.

Describe alternatives you've considered

  • validationMethod: "submit-only" works but is turning off early validation for the whole schema

macmillen avatar Apr 08 '24 21:04 macmillen

I'd suggest making a derived/proxy store for this, based on $errors, but will store a list of errors that have been added manually, and replace them for those paths.

ciscoheat avatar Apr 08 '24 21:04 ciscoheat

I see what you mean, unfortunately I don't see a way for this to work with customValidity enabled which I decided to use for simplicity's sake. Do you have an idea on how to achieve this?

I have the feeling it would be much easier to handle this internally like providing a way to merge server errors with superForms errors or otherwise I feel like there will be a lot of side-effects.

macmillen avatar May 31 '24 12:05 macmillen

Now I managed to display server errors with setCustomValidity enabled but there is still the issue that only one and not all input fields get a validity state applied. Is there a way to trigger setCustomValidity on all input elements?

I created a repro to demonstrate the issue: https://www.sveltelab.dev/2b04shwpzvgw2li

macmillen avatar May 31 '24 14:05 macmillen