fix(health): redact failure diagnostics

This commit is contained in:
Amp
2026-08-21 05:08:00 +00:00
parent 5570c5ffac
commit f79f18acbf
2 changed files with 22 additions and 3 deletions
+3 -2
View File
@@ -6,6 +6,7 @@ import { colorize, isRich, theme } from "../../packages/terminal-core/src/theme.
import { formatChannelStatusState } from "../channels/plugins/status-state.js";
import { isGatewayTransportError } from "../gateway/call.js";
import type { ChannelAccountHealthSummary, HealthSummary } from "../gateway/health/types.js";
import { redactSensitiveText } from "../logging/redact.js";
export function formatGatewayClosedDiagnostic(err: unknown): string | undefined {
if (!isGatewayTransportError(err) || err.kind !== "closed" || err.code === undefined) {
@@ -35,8 +36,8 @@ const formatKv = (line: string, rich: boolean) => {
/** Formats thrown health errors with rich detail lines when terminal color is enabled. */
export function formatHealthCheckFailure(err: unknown, opts: { rich?: boolean } = {}): string {
const rich = opts.rich ?? isRich();
const raw = String(err);
const message = err instanceof Error ? err.message : raw;
const raw = redactSensitiveText(String(err));
const message = err instanceof Error ? redactSensitiveText(err.message) : raw;
if (!rich) {
return `Health check failed: ${raw}`;
+19 -1
View File
@@ -1,7 +1,9 @@
// Health command tests cover gateway health probes, JSON output, and status formatting.
import { beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { GatewayClientRequestError } from "../../packages/gateway-client/src/index.js";
import { stripAnsi } from "../../packages/terminal-core/src/ansi.js";
import { registerSecretValueForRedaction } from "../logging/secret-redaction-registry.js";
import { resetSecretRedactionRegistryForTest } from "../logging/secret-redaction-registry.test-support.js";
import { ExitError } from "../runtime.js";
import {
buildCredentialsRequiredHealthDiagnostic,
@@ -26,6 +28,10 @@ const runtime = {
exit: vi.fn(),
};
afterEach(() => {
resetSecretRedactionRegistryForTest();
});
const defaultSessions: HealthSummary["sessions"] = {
path: "/tmp/sessions.json",
count: 0,
@@ -908,6 +914,18 @@ describe("formatConfigReloadHealthLine", () => {
});
describe("formatHealthCheckFailure", () => {
it.each([false, true])("redacts registered secrets from rich=%s output", (rich) => {
const registeredSecret = "qa-health-check-secret";
registerSecretValueForRedaction(registeredSecret);
const output = formatHealthCheckFailure(new Error(`gateway failed with ${registeredSecret}`), {
rich,
});
expect(output).toContain("gateway failed with");
expect(output).not.toContain(registeredSecret);
});
it("keeps non-rich output stable", () => {
const err = new Error("gateway closed (1006 abnormal closure): no close reason");
expect(formatHealthCheckFailure(err, { rich: false })).toBe(