Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145import { Data } from "effect";import { describe, expect, it } from "vite-plus/test";
import { categorizeError, getErrorDetails, isForbiddenError, isNetworkError, isNotFoundError, isRetryableError, isServerError, isValidationError,} from "./error-types";
const taggedError = (tag: string, message?: string) => Data.tagged<{ _tag: string; message?: string }>(tag)({ message });
describe("categorizeError", () => { it("should categorize by known tag", () => { expect(categorizeError(taggedError("NetworkError"))).toBe("network"); expect(categorizeError(taggedError("TimeoutError"))).toBe("network"); expect(categorizeError(taggedError("NotFoundError"))).toBe("not-found"); expect(categorizeError(taggedError("GoalMapNotFoundError"))).toBe("not-found"); expect(categorizeError(taggedError("ForbiddenError"))).toBe("forbidden"); expect(categorizeError(taggedError("ValidationError"))).toBe("validation"); expect(categorizeError(taggedError("DatabaseError"))).toBe("server"); });
it("should categorize by message patterns when tag is unknown", () => { expect(categorizeError(taggedError("CustomError", "failed to fetch"))).toBe("network"); expect(categorizeError(taggedError("CustomError", "not found"))).toBe("not-found"); expect(categorizeError(taggedError("CustomError", "unauthorized"))).toBe("forbidden"); expect(categorizeError(taggedError("CustomError", "validation failed"))).toBe("validation"); expect(categorizeError(taggedError("CustomError", "internal server error"))).toBe("server"); });
it("should categorize Error instances by message", () => { expect(categorizeError(new Error("Failed to fetch"))).toBe("network"); expect(categorizeError(new Error("404 not found"))).toBe("not-found"); expect(categorizeError(new Error("Forbidden"))).toBe("forbidden"); expect(categorizeError(new Error("Invalid input"))).toBe("validation"); expect(categorizeError(new Error("500 server error"))).toBe("server"); });
it("should categorize plain strings", () => { expect(categorizeError("connection timeout")).toBe("network"); expect(categorizeError("resource missing")).toBe("not-found"); expect(categorizeError("access denied")).toBe("forbidden"); });
it("should categorize by error property in object", () => { expect(categorizeError({ error: "NetworkError" })).toBe("network"); });
it("should return unknown for unrecognized errors", () => { expect(categorizeError({ random: "thing" })).toBe("unknown"); expect(categorizeError(null)).toBe("unknown"); expect(categorizeError(42)).toBe("unknown"); });
it("should prioritize tag over message when both present", () => { expect(categorizeError(taggedError("NetworkError", "everything is fine"))).toBe("network"); expect(categorizeError(taggedError("ValidationError", "invalid"))).toBe("validation"); });});
describe("getErrorDetails", () => { it("should return user-friendly message for internal errors", () => { const details = getErrorDetails(new Error("Internal server error")); expect(details.message).toContain("went wrong on our end"); expect(details.category).toBe("server"); expect(details.isRetryable).toBe(true); expect(details.showToUser).toBe(true); });
it("should use raw message for non-internal errors", () => { const details = getErrorDetails(new Error("Invalid email address")); expect(details.message).toBe("Invalid email address"); expect(details.category).toBe("validation"); expect(details.isRetryable).toBe(false); });
it("should mark network and server errors as retryable", () => { expect(getErrorDetails(new Error("Failed to fetch")).isRetryable).toBe(true); expect(getErrorDetails(new Error("500 error")).isRetryable).toBe(true); expect(getErrorDetails(new Error("Not found")).isRetryable).toBe(false); expect(getErrorDetails(new Error("Forbidden")).isRetryable).toBe(false); });
it("should handle tagged errors", () => { const details = getErrorDetails(taggedError("GoalMapNotFoundError")); expect(details.category).toBe("not-found"); expect(details.message).toBe("GoalMapNotFoundError"); });
it("should handle string errors", () => { const details = getErrorDetails("connection timeout"); expect(details.category).toBe("network"); });
it("should handle unknown error shapes", () => { const details = getErrorDetails({ error: "forbidden" }); expect(details.category).toBe("forbidden"); });});
describe("error type guards", () => { it("isNetworkError", () => { expect(isNetworkError(new Error("Failed to fetch"))).toBe(true); expect(isNetworkError(new Error("Not found"))).toBe(false); expect(isNetworkError(taggedError("NetworkError"))).toBe(true); });
it("isNotFoundError", () => { expect(isNotFoundError(new Error("Not found"))).toBe(true); expect(isNotFoundError(new Error("Server error"))).toBe(false); expect(isNotFoundError(taggedError("NotFoundError"))).toBe(true); });
it("isForbiddenError", () => { expect(isForbiddenError(new Error("Forbidden"))).toBe(true); expect(isForbiddenError(new Error("Not found"))).toBe(false); expect(isForbiddenError(taggedError("ForbiddenError"))).toBe(true); });
it("isValidationError", () => { expect(isValidationError(new Error("Invalid input"))).toBe(true); expect(isValidationError(new Error("Not found"))).toBe(false); expect(isValidationError(taggedError("ValidationError"))).toBe(true); });
it("isServerError", () => { expect(isServerError(new Error("Internal server error"))).toBe(true); expect(isServerError(new Error("Not found"))).toBe(false); expect(isServerError(taggedError("ServerError"))).toBe(true); });
it("isRetryableError", () => { expect(isRetryableError(new Error("Failed to fetch"))).toBe(true); expect(isRetryableError(new Error("Internal server error"))).toBe(true); expect(isRetryableError(new Error("Not found"))).toBe(false); expect(isRetryableError(new Error("Invalid input"))).toBe(false); });});