modular-forms icon indicating copy to clipboard operation
modular-forms copied to clipboard

The wrong status code is returned when throwing a FormError

Open DustinJSilk opened this issue 10 months ago • 2 comments

When throwing a FormError, we'd expect a non-200 status code to be used in the response and the status code of the HTTP to match it. For example:

const res = await action.submit(data)
res.status === 200 // <- should be 500

As additional topics to discuss, in this RFC https://github.com/QwikDev/qwik-evolution/issues/205 we're planning on standardising Qwik errors. Part of this work is that server errors should also throw on the frontend so they can be caught rather than having the error response returned successfully in the response object. This is so that we don't need to handle transient errors differently from our thrown errors.

With the introduction of ServerError types in Qwik, we can set the status code for errors being thrown, it seems like this would make sense to work with ModuleForms as well otherwise we're unable to differentiate between error types correctly in code and in our monitoring.

So something like this might make sense for the FormError, which throws a ServerError in Qwik:

export declare class FormError<TFieldValues extends FieldValues> extends Error {
    readonly name = "FormError";
    readonly errors: FormErrors<TFieldValues>;
    readonly code: number;
    readonly message: string;

    constructor(statusCode: number, message: string, errors?: Maybe<FormErrors<TFieldValues>>);
    constructor(message: string, errors?: Maybe<FormErrors<TFieldValues>>);
    constructor(errors: FormErrors<TFieldValues>);
}

There is also some confusion, at least from me, with using the Qwik error throw event.fail(500, {...})

And then a more useful client side error handling would be this:

try {
  const res = await action.submit(data)
} catch (err) {
  if (err instanceof FormError) {
    // ... handle error
  }
  // handle unknown errors
}

In Qwik we will use the ServerError going forward so that we can handle it in middleware correctly. So we should possibly have the FormError extend the ServerError, at least for Qwik apps.

DustinJSilk avatar Feb 01 '25 12:02 DustinJSilk

It also seems like a second issue is that after setting the response, Qwik refetches the loaders on the page and rerenders which updates the form state which resets the response. So the response is removed when the initial data is returned by a routeLoader

DustinJSilk avatar Feb 01 '25 12:02 DustinJSilk

Thank you for creating this issue. Are you interested in creating a PR? Or do we need to wait for a new Qwik version first?

fabian-hiller avatar Feb 03 '25 04:02 fabian-hiller