123 lines
3.8 KiB
TypeScript
123 lines
3.8 KiB
TypeScript
import { SuaveplanError } from "@suaveplan/error";
|
|
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import {
|
|
FALLBACK_URI_CODES,
|
|
FallbackUriError,
|
|
} from "../error-codes/error-codes.js";
|
|
import { FallbackPolicySchema } from "../types/policy.schemas.js";
|
|
import type { FallbackPolicy } from "../types/policy.types.js";
|
|
import { classify } from "./classify.js";
|
|
|
|
const POLICY: FallbackPolicy = FallbackPolicySchema.parse({});
|
|
const ANY_POLICY: FallbackPolicy = FallbackPolicySchema.parse({
|
|
errorClass: "any",
|
|
});
|
|
|
|
class TestErr extends SuaveplanError<string> {
|
|
public constructor(code: string) {
|
|
super(code, "test");
|
|
}
|
|
}
|
|
|
|
describe("classify", () => {
|
|
it("classifies NOT_FOUND as fall-through-eligible", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(classify(new TestErr("STORAGE_URI.NOT_FOUND"), POLICY)).toBe(
|
|
"transient"
|
|
);
|
|
});
|
|
|
|
it("classifies UNKNOWN_SCHEME as semantic under default", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(
|
|
classify(new TestErr("STORAGE_URI.UNKNOWN_SCHEME"), POLICY)
|
|
).toBe("semantic");
|
|
});
|
|
|
|
it("classifies UNKNOWN_SCHEME as transient under errorClass=any", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(
|
|
classify(new TestErr("STORAGE_URI.UNKNOWN_SCHEME"), ANY_POLICY)
|
|
).toBe("transient");
|
|
});
|
|
|
|
it("treats MAX_DEPTH_EXCEEDED as semantic regardless of policy", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const err = new FallbackUriError(
|
|
FALLBACK_URI_CODES.MAX_DEPTH_EXCEEDED,
|
|
"x"
|
|
);
|
|
expect(classify(err, POLICY)).toBe("semantic");
|
|
expect(classify(err, ANY_POLICY)).toBe("semantic");
|
|
});
|
|
|
|
it("treats CIRCULAR_REFERENCE as semantic regardless of policy", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const err = new FallbackUriError(
|
|
FALLBACK_URI_CODES.CIRCULAR_REFERENCE,
|
|
"x"
|
|
);
|
|
expect(classify(err, ANY_POLICY)).toBe("semantic");
|
|
});
|
|
|
|
it("classifies ABORTED codes as abort", { timeout: 5000 }, () => {
|
|
expect(
|
|
classify(
|
|
new FallbackUriError(FALLBACK_URI_CODES.ABORTED, "x"),
|
|
POLICY
|
|
)
|
|
).toBe("abort");
|
|
expect(classify(new TestErr("STORAGE_URI.ABORTED"), POLICY)).toBe(
|
|
"abort"
|
|
);
|
|
});
|
|
|
|
it("classifies ADAPTER_ERROR as transient", { timeout: 5000 }, () => {
|
|
expect(classify(new TestErr("STORAGE_URI.ADAPTER_ERROR"), POLICY)).toBe(
|
|
"transient"
|
|
);
|
|
});
|
|
|
|
it("classifies generic semantic codes as semantic", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(classify(new TestErr("STORAGE_URI.INVALID_URI"), POLICY)).toBe(
|
|
"semantic"
|
|
);
|
|
expect(
|
|
classify(new TestErr("STORAGE_URI.WRITE_UNSUPPORTED"), POLICY)
|
|
).toBe("semantic");
|
|
expect(
|
|
classify(new TestErr("STORAGE_URI.LIST_UNSUPPORTED"), POLICY)
|
|
).toBe("semantic");
|
|
expect(
|
|
classify(new TestErr("STORAGE_URI.SCHEME_CONFLICT"), POLICY)
|
|
).toBe("semantic");
|
|
});
|
|
|
|
it("classifies unknown namespaced codes per policy", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(classify(new TestErr("FOO.BAR"), POLICY)).toBe("semantic");
|
|
expect(classify(new TestErr("FOO.BAR"), ANY_POLICY)).toBe("transient");
|
|
});
|
|
|
|
it("classifies AbortError name as abort", { timeout: 5000 }, () => {
|
|
const e = new Error("aborted");
|
|
e.name = "AbortError";
|
|
expect(classify(e, POLICY)).toBe("abort");
|
|
});
|
|
|
|
it("classifies unknown thrown values as transient", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(classify("boom", POLICY)).toBe("transient");
|
|
expect(classify(new Error("plain"), POLICY)).toBe("transient");
|
|
});
|
|
});
|