test: add comprehensive tests for isTransientError utility
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 17m44s

This commit is contained in:
Hoid 2026-02-28 20:03:14 +01:00
parent 597be6bcae
commit a91b4c53a9

View file

@ -0,0 +1,199 @@
import { describe, it, expect } from "vitest";
import { isTransientError } from "../utils/errors.js";
describe("isTransientError", () => {
describe("null/undefined/empty input", () => {
it("returns false for null", () => {
expect(isTransientError(null)).toBe(false);
});
it("returns false for undefined", () => {
expect(isTransientError(undefined)).toBe(false);
});
it("returns false for empty object", () => {
expect(isTransientError({})).toBe(false);
});
});
describe("error codes from TRANSIENT_ERRORS set", () => {
it("returns true for ECONNRESET", () => {
expect(isTransientError({ code: "ECONNRESET" })).toBe(true);
});
it("returns true for ECONNREFUSED", () => {
expect(isTransientError({ code: "ECONNREFUSED" })).toBe(true);
});
it("returns true for EPIPE", () => {
expect(isTransientError({ code: "EPIPE" })).toBe(true);
});
it("returns true for ETIMEDOUT", () => {
expect(isTransientError({ code: "ETIMEDOUT" })).toBe(true);
});
it("returns true for CONNECTION_LOST", () => {
expect(isTransientError({ code: "CONNECTION_LOST" })).toBe(true);
});
it("returns true for 57P01 (admin_shutdown)", () => {
expect(isTransientError({ code: "57P01" })).toBe(true);
});
it("returns true for 57P02 (crash_shutdown)", () => {
expect(isTransientError({ code: "57P02" })).toBe(true);
});
it("returns true for 57P03 (cannot_connect_now)", () => {
expect(isTransientError({ code: "57P03" })).toBe(true);
});
it("returns true for 08006 (connection_failure)", () => {
expect(isTransientError({ code: "08006" })).toBe(true);
});
it("returns true for 08003 (connection_does_not_exist)", () => {
expect(isTransientError({ code: "08003" })).toBe(true);
});
it("returns true for 08001 (sqlclient_unable_to_establish_sqlconnection)", () => {
expect(isTransientError({ code: "08001" })).toBe(true);
});
});
describe("message substring matching", () => {
it("returns true for 'no available server'", () => {
expect(isTransientError({ message: "no available server" })).toBe(true);
});
it("returns true for 'connection terminated'", () => {
expect(isTransientError({ message: "connection terminated unexpectedly" })).toBe(true);
});
it("returns true for 'connection refused'", () => {
expect(isTransientError({ message: "connection refused by server" })).toBe(true);
});
it("returns true for 'server closed the connection'", () => {
expect(isTransientError({ message: "server closed the connection unexpectedly" })).toBe(true);
});
it("returns true for 'timeout expired'", () => {
expect(isTransientError({ message: "timeout expired waiting for connection" })).toBe(true);
});
});
describe("case-insensitive message matching", () => {
it("returns true for 'No Available Server' (mixed case)", () => {
expect(isTransientError({ message: "No Available Server" })).toBe(true);
});
it("returns true for 'CONNECTION TERMINATED' (uppercase)", () => {
expect(isTransientError({ message: "CONNECTION TERMINATED" })).toBe(true);
});
it("returns true for 'Connection Refused' (title case)", () => {
expect(isTransientError({ message: "Connection Refused" })).toBe(true);
});
it("returns true for 'SERVER CLOSED THE CONNECTION' (uppercase)", () => {
expect(isTransientError({ message: "SERVER CLOSED THE CONNECTION" })).toBe(true);
});
it("returns true for 'Timeout Expired' (title case)", () => {
expect(isTransientError({ message: "Timeout Expired" })).toBe(true);
});
});
describe("non-transient errors", () => {
it("returns false for syntax error", () => {
expect(isTransientError({
code: "42601",
message: "syntax error at or near SELECT"
})).toBe(false);
});
it("returns false for unique constraint violation", () => {
expect(isTransientError({
code: "23505",
message: "duplicate key value violates unique constraint"
})).toBe(false);
});
it("returns false for foreign key violation", () => {
expect(isTransientError({
code: "23503",
message: "foreign key constraint violation"
})).toBe(false);
});
it("returns false for not null violation", () => {
expect(isTransientError({
code: "23502",
message: "null value in column violates not-null constraint"
})).toBe(false);
});
it("returns false for permission denied", () => {
expect(isTransientError({
code: "42501",
message: "permission denied for table users"
})).toBe(false);
});
});
describe("unrelated codes and messages", () => {
it("returns false for unrelated error code", () => {
expect(isTransientError({ code: "UNKNOWN_ERROR" })).toBe(false);
});
it("returns false for unrelated error message", () => {
expect(isTransientError({ message: "Something went wrong" })).toBe(false);
});
it("returns false for generic database error", () => {
expect(isTransientError({
code: "P0001",
message: "Database operation failed"
})).toBe(false);
});
it("returns false for application error", () => {
expect(isTransientError({
message: "Invalid user input"
})).toBe(false);
});
});
describe("edge cases", () => {
it("returns true when both code and message match", () => {
expect(isTransientError({
code: "ECONNRESET",
message: "connection terminated"
})).toBe(true);
});
it("returns true when only code matches", () => {
expect(isTransientError({
code: "ETIMEDOUT",
message: "some other message"
})).toBe(true);
});
it("returns true when only message matches", () => {
expect(isTransientError({
code: "SOME_CODE",
message: "no available server to connect"
})).toBe(true);
});
it("returns false for error with only unrelated code", () => {
expect(isTransientError({ code: "NOTFOUND" })).toBe(false);
});
it("returns false for error with empty message", () => {
expect(isTransientError({ message: "" })).toBe(false);
});
});
});