polar icon indicating copy to clipboard operation
polar copied to clipboard

Improve error handling in the ProductForm component

Open taranek opened this issue 4 months ago • 5 comments

Description

The product creation form fails with no visual feedback for the user.

Technical deepdive ⚙️

The backend request fails (422 error) with a following response

{
    "error": "RequestValidationError",
    "detail": [
        {
            "type": "missing",
            "loc": [
                "body",
                "prices",
                0,
                "ProductPriceFixedCreate",
                "amount_type"
            ],
            "msg": "Field required",
            "input": {
                "price_currency": "usd",
                "id": ""
            }
        }
    // + 6 other fields
    ....]
}

That seems OK, but it the control for the prices[0].amount_type field is not rendered in the UI, hence there are no UI elements to attach the error to.

Additionally, the useCreateProduct().isSuccess equals true because the api.POST('/v1/products/', { body }) promise is not rejected if response.status === 422.

  useMutation({
    mutationFn: (body: schemas['ProductCreate']) => {
      return api.POST('/v1/products/', { body })
    },
    onSuccess: async (result, _variables, _ctx) => {
      if (result.error) {
        return
      }
   // ... rest of the code
}})

What we could do is throw an error in the mutationFn if request.error is present - this should set useCreateProduct().isSuccess to false.

It would also be nice to have a toast with an error every time your request fails. This can be handled in at least two ways:

  1. On the component level (e.g., in handleSubmit, which allows displaying a more detailed error to the user)
  2. Globally for the whole tanstack-query client (although that would require changing the rest of the useMutation hooks).
import { QueryClient } from '@tanstack/react-query'

export const queryClient = new QueryClient({
  defaultOptions: {
    mutations: {
      onError: () => {
        toast({
          title: 'An error occurred',
          description: 'Please try again later.',
        })
      }
    }

An easy fix to move faster with the product 💡

Set the FIxed Price price type (instead of undefined) by default so that the price field gets red after a failed request, which shows the user what field needs to be corrected.

Current Behavior

  1. Open the "create product" form
  2. Fill the name input with some value.
  3. Try to submit the form
  4. The request fails, but the error is not displayed in the UI. Additionally, the form cannot be resubmitted.

Expected Behavior

  1. A descriptive and accessible error message is displayed to the user. The form can be resubmitted

Screenshots

Please disregard the React DevTools highlighting (that's not part of this issue, although re-rendering the whole form might become a bottleneck in some cases):

https://github.com/user-attachments/assets/20210b2a-9d93-4f70-85e0-75ab4a207cb0

Environment:

  • Operating System: all
  • Browser: all

taranek avatar Jul 05 '25 11:07 taranek