import { ApiError } from "../../../bridge/types/Errors.js"; import { isRetryable, mapBridgeError } from "../errors/mapBridgeError.js"; /** * Parameters for the useBridgeError hook */ interface UseBridgeErrorParams { /** * The error to process. Can be an ApiError or generic Error. */ error: Error | ApiError | null | undefined; } /** * Result returned by the useBridgeError hook */ interface UseBridgeErrorResult { /** * The mapped/normalized error, null if no error provided */ mappedError: ApiError | null; /** * Whether this error can be retried */ isRetryable: boolean; /** * User-friendly error message */ userMessage: string; /** * Technical error code for debugging */ errorCode: string | null; /** * HTTP status code if available */ statusCode: number | null; /** * Whether this is a client-side error (4xx) */ isClientError: boolean; /** * Whether this is a server-side error (5xx) */ isServerError: boolean; } /** * Hook that processes bridge errors using mapBridgeError and isRetryable * * @param params - Parameters containing the error to process * @returns Processed error information with retry logic and user-friendly messages * * @example * ```tsx * const { data, error } = useBridgeRoutes({ client, originChainId: 1 }); * const { * mappedError, * isRetryable, * userMessage, * isClientError * } = useBridgeError({ error }); * * if (error) { * return ( *
*

{userMessage}

* {isRetryable && } *
* ); * } * ``` */ export function useBridgeError( params: UseBridgeErrorParams, ): UseBridgeErrorResult { const { error } = params; // No error case if (!error) { return { errorCode: null, isClientError: false, isRetryable: false, isServerError: false, mappedError: null, statusCode: null, userMessage: "", }; } // Convert to ApiError if it's not already let apiError: ApiError; if (error instanceof ApiError) { apiError = mapBridgeError(error); } else { // Create ApiError from generic Error apiError = new ApiError({ code: "UNKNOWN_ERROR", message: error.message || "An unknown error occurred", statusCode: 500, // Default for generic errors }); } const statusCode = apiError.statusCode || null; const isClientError = statusCode !== null && statusCode >= 400 && statusCode < 500; const isServerError = statusCode !== null && statusCode >= 500; // Generate user-friendly message based on error code const userMessage = getUserFriendlyMessage(apiError); return { errorCode: apiError.code, isClientError, isRetryable: isRetryable(apiError.code), isServerError, mappedError: apiError, statusCode, userMessage, }; } /** * Converts technical error codes to user-friendly messages */ function getUserFriendlyMessage(error: ApiError): string { switch (error.code) { case "INVALID_INPUT": return "Invalid input provided. Please check your parameters and try again."; case "ROUTE_NOT_FOUND": return "No route found for this transaction. Please try a different token pair or amount."; case "AMOUNT_TOO_LOW": return "The amount is too low for this transaction. Please increase the amount."; case "AMOUNT_TOO_HIGH": return "The amount is too high for this transaction. Please decrease the amount."; case "INTERNAL_SERVER_ERROR": return "A temporary error occurred. Please try again in a moment."; default: // Fallback to the original error message if available return error.message || "An unexpected error occurred. Please try again."; } }