All files / src/utils errorHandlers.ts

100% Statements 40/40
100% Branches 14/14
100% Functions 2/2
100% Lines 40/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 751x     1x 1x 1x                                       1x 5x 5x   5x 5x 4x 3x 2x 5x 3x 3x 3x 3x 3x 3x     2x 2x 5x 5x 5x 5x               1x 6x 6x 6x 6x 6x 1x 5x 4x 1x   6x     6x 3x 3x 6x  
import { toast } from 'sonner';
 
// Constants
import { STATUS_CODE, STATUS_MESSAGES } from '@shared/constants';
import { ERROR_MESSAGES } from '@/constants';
import { AUTH_ERROR_MESSAGES, SILENT_ERROR_MESSAGES } from '@/constants';
 
// Types
import { HttpResponse } from '@shared/types';
 
/**
 * Handle errors in server actions - re-throws 401 and 403 role mismatch errors, returns formatted response for others
 * @param error - The error to handle
 * @returns Formatted error response or re-throws 401/403 role mismatch errors
 *
 * @example
 * ```typescript
 * try {
 *   const response = await httpClient(...);
 *   return response;
 * } catch (error) {
 *   return handleActionError<MyDataType>(error);
 * }
 * ```
 */
export const handleActionError = <T = null>(
  error: unknown,
): HttpResponse<T> => {
  // Re-throw 401 and 403 role mismatch errors to be handled by HOCs
  if (
    error instanceof Error &&
    (error.message === STATUS_MESSAGES[STATUS_CODE.UNAUTHORIZED] ||
      error.message === AUTH_ERROR_MESSAGES.ROLE_MISMATCH ||
      error.message === AUTH_ERROR_MESSAGES.ACCOUNT_DEACTIVATED)
  ) {
    return {
      data: null as T,
      error: error.message,
      status: STATUS_CODE.FORBIDDEN,
    };
  }
 
  // Return formatted error response for other errors
  return {
    data: null as T,
    error: error instanceof Error ? error.message : ERROR_MESSAGES.DEFAULT,
    status: STATUS_CODE.INTERNAL_SERVER_ERROR,
  };
};
 
/**
 * Display error toast notification with filtering capability
 *
 * @param error - The error to potentially display (Error object or string)
 * @param silentErrors - Additional error messages to ignore (optional)
 */
export const showErrorToast = (
  error: unknown,
  silentErrors: string[] = [],
): void => {
  const errorMessage =
    error instanceof Error
      ? error.message
      : typeof error === 'string'
        ? error
        : STATUS_MESSAGES[STATUS_CODE.INTERNAL_SERVER_ERROR];
 
  const allSilentErrors = [...SILENT_ERROR_MESSAGES, ...silentErrors];
 
  // Don't show toast if error message should be handled silently
  if (!allSilentErrors.includes(errorMessage)) {
    toast.error(`Error: ${errorMessage}`);
  }
};