emilkowalski / sonner

An opinionated toast component for React.

Home Page:https://sonner.emilkowal.ski

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request]: Use JSON body error message in toast.promise

jamesindeed opened this issue · comments

Feature Request: Enhanced Error Handling with Custom JSON Responses

Overview

Firstly, I want to express my admiration for the exceptional toast package and the dedication put into its development.

Proposal

I would like to suggest an enhancement to the toast.promise functionality. Currently, the error message is constructed based on the HTTP status or a predefined custom message. However, i believe it would be beneficial to extend this capability to handle custom errors from the JSON body. This idea comes from this being how I return data from my API:

export type Safe<T, E = string> =
    | {
          data: T;
          success: true;
      }
    | {
          success: false;
          error: E;
      };

Current implementation in the package

const message = typeof data.error === 'function' ? data.error(`HTTP error! status: ${response.status}`) : data.error;

View in Code

Benefits

  • Improved customization: Users can tailor error messages based on the specifics of the JSON response.
  • Enhanced error reporting: Deeper insights into the nature of errors for better debugging.

Conclusion

I believe this enhancement would improve the toast package, offering users a more versatile and comprehensive error-handling experience.

Thank you for considering this feature request!

commented

You can encapsulate a fetcher to control what form the thrown errors should take, for example:

export class HTTPError extends Error {
  data: ErrorResponse;
  status: number;
  constructor(message: string, data: ErrorResponse, status: number) {
    super(message);
    this.data = data;
    this.status = status;
  }
}

export async function fetcher<T>(key: string, options?: RequestInit): Promise<T> {
  const res = await fetch(new URL(key, base), {
    ...options
  });

  const data = res.headers.get('Content-Type')?.includes('application/json')
    ? await res.json()
    : await res.text();

  if (!res.ok) {
    if (typeof data === 'object' && 'message' in data)
      throw new HTTPError(data.message, data, res.status);
    else
      throw new Error('An error occurred while fetching the data.');
  }

  return data as T;
}

Stumbled on this because I also wanted to customize the error message from the promise. I love the toast.promise makes the written code super clean.

I'll take a look over the weekend, maybe I can smash out a PR for it.