// src/utils/errors.integration.test.ts
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { ComposeOperationError, HostOperationError, logError, SSHCommandError } from "./errors.js";
describe("Error Handling Integration", () => {
let consoleErrorSpy: ReturnType<typeof vi.spyOn>;
beforeEach(() => {
consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {
/* Mock implementation */
});
});
afterEach(() => {
consoleErrorSpy.mockRestore();
});
it("should preserve full error chain through multiple layers", () => {
const rootCause = new Error("ECONNREFUSED");
const sshError = new SSHCommandError(
"SSH failed",
"docker-01",
"docker ps",
255,
"Connection refused",
"",
rootCause
);
const hostError = new HostOperationError(
"List containers failed",
"docker-01",
"listContainers",
sshError
);
// Verify chain
expect(hostError.cause).toBe(sshError);
expect(sshError.cause).toBe(rootCause);
// Verify stack includes all layers
expect(hostError.stack).toContain("HostOperationError");
expect(hostError.stack).toContain("Caused by:");
});
it("should log complete context for chained errors", () => {
const rootCause = new Error("Network timeout");
const error = new ComposeOperationError(
"Service start failed",
"web-01",
"production",
"up",
rootCause
);
logError(error, {
requestId: "req-456",
metadata: { retryAttempt: 3 },
});
// Verify logging happened via console.error
expect(consoleErrorSpy).toHaveBeenCalled();
const logOutput = consoleErrorSpy.mock.calls.map((call) => call.join(" ")).join(" ");
expect(logOutput).toContain("req-456");
expect(logOutput).toContain("web-01");
expect(logOutput).toContain("production");
});
});