All files / packages/utils/src error.ts

100% Statements 42/42
100% Branches 42/42
100% Functions 5/5
100% Lines 38/38

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 75 76 77 78 79 80 81 82 83 84 85    9x 23x                   1x 19x 11x     8x 8x     2x     14x 10x     4x     10x     12x 12x 1x     11x 1x     10x 3x     7x 7x 7x 1x     6x 6x 3x 3x 1x       5x 5x 3x 3x 2x     2x 1x         4x     2x       2x    
import { HttpError } from "@repo/types/http";
 
export const isHttpError = <T = unknown>(err: unknown): err is HttpError<T> => {
  return (
    typeof err === "object" &&
    err !== null &&
    "ok" in err &&
    (err as Record<string, unknown>).ok === false &&
    "status" in err &&
    "data" in err
  );
};
 
const getStringMessage = (value: unknown): string | undefined => {
  if (typeof value !== "string") {
    return undefined;
  }
 
  const normalizedMessage = value.trim();
  return normalizedMessage.length > 0 ? normalizedMessage : undefined;
};
 
export const getHttpErrorMessage = <T extends { message?: unknown } = { message?: unknown }>(
  err: unknown,
): string | undefined => {
  if (!isHttpError<T>(err)) {
    return undefined;
  }
 
  return getStringMessage(err.data?.message) ?? getStringMessage(err.statusText);
};
 
export const getErrorMessage = <T extends { message?: unknown } = { message?: unknown }>(
  err: unknown,
): string | undefined => {
  const httpMessage = getHttpErrorMessage<T>(err);
  if (httpMessage) {
    return httpMessage;
  }
 
  if (err instanceof Error) {
    return getStringMessage(err.message);
  }
 
  if (!err || typeof err !== "object") {
    return undefined;
  }
 
  const errorObject = err as Record<string, unknown>;
  const directMessage = getStringMessage(errorObject.message);
  if (directMessage) {
    return directMessage;
  }
 
  const nestedData = errorObject.data;
  if (nestedData && typeof nestedData === "object") {
    const nestedDataMessage = getStringMessage((nestedData as Record<string, unknown>).message);
    if (nestedDataMessage) {
      return nestedDataMessage;
    }
  }
 
  const nestedResponse = errorObject.response;
  if (nestedResponse && typeof nestedResponse === "object") {
    const responseData = (nestedResponse as Record<string, unknown>).data;
    if (responseData && typeof responseData === "object") {
      const responseDataMessage = getStringMessage(
        (responseData as Record<string, unknown>).message,
      );
      if (responseDataMessage) {
        return responseDataMessage;
      }
    }
  }
 
  return undefined;
};
 
export const resolveHttpErrorMessage = <T extends { message?: unknown } = { message?: unknown }>(
  err: unknown,
  fallbackMessage: string,
): string => {
  return getErrorMessage<T>(err) ?? fallbackMessage;
};