feat: add sentinel error detail deep links
This commit is contained in:
@@ -254,6 +254,15 @@ export function runSentinelReport(state: SentinelCicdState, options: Extract<Web
|
||||
return rendered(report.ok && body.ok !== false, command, renderedText);
|
||||
}
|
||||
|
||||
export function runSentinelErrorDetail(state: SentinelCicdState, options: Extract<WebProbeSentinelOptions, { kind: "error" }>): RenderedCliResult {
|
||||
const command = "web-probe sentinel error get";
|
||||
const response = callSentinelService(state, "GET", `/api/errors/${encodeURIComponent(options.errorId)}`, null, options.timeoutSeconds);
|
||||
const body = record(response.bodyJson);
|
||||
const rawPayload = Object.keys(body).length > 0 ? body : response;
|
||||
if (options.full || options.raw) return rendered(response.ok && body.ok !== false, command, JSON.stringify(rawPayload, null, 2));
|
||||
return rendered(response.ok && body.ok !== false, command, renderSentinelErrorDetailResult({ command, node: state.spec.nodeId, lane: state.spec.lane, sentinelId: state.sentinelId, response, body, valuesRedacted: true }));
|
||||
}
|
||||
|
||||
function compactSentinelReportRawPayload(
|
||||
state: SentinelCicdState,
|
||||
body: Record<string, unknown>,
|
||||
@@ -580,6 +589,8 @@ function compactSentinelReportFinding(value: Record<string, unknown>): Record<st
|
||||
summary: reportText(value.summary ?? value.message, 220),
|
||||
valuesRedacted: true,
|
||||
};
|
||||
const errorId = stringAtNullable(value, "errorId");
|
||||
if (errorId !== null) result.errorId = errorId;
|
||||
const rootCause = stringAtNullable(value, "rootCause");
|
||||
if (rootCause !== null) result.rootCause = rootCause;
|
||||
const rootCauseStatus = stringAtNullable(value, "rootCauseStatus");
|
||||
@@ -2089,3 +2100,49 @@ function renderReportResult(result: Record<string, unknown>): string {
|
||||
" report reads sentinel indexed analyze summaries/views only; it does not resample, rerun analyze, or read Workbench.",
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
function renderSentinelErrorDetailResult(result: Record<string, unknown>): string {
|
||||
const body = record(result.body);
|
||||
const detail = record(body.detail);
|
||||
const identity = record(detail.identity);
|
||||
const evidence = record(detail.sentinelEvidence);
|
||||
const otel = record(detail.otel);
|
||||
const finding = record(body.finding);
|
||||
const links = record(detail.links);
|
||||
return [
|
||||
String(result.command),
|
||||
"",
|
||||
table(["NODE", "LANE", "STATUS", "ERROR_ID", "RUN", "FINDING"], [[
|
||||
result.node,
|
||||
result.lane,
|
||||
body.ok === false ? "blocked" : "ok",
|
||||
body.errorId ?? identity.errorId ?? "-",
|
||||
record(body.run).id ?? identity.runId ?? "-",
|
||||
identity.findingId ?? finding.id ?? "-",
|
||||
]]),
|
||||
"",
|
||||
table(["LEVEL", "BLOCKING", "TITLE", "SUMMARY"], [[
|
||||
identity.severity ?? finding.severity ?? "-",
|
||||
evidence.blocking === true ? "yes" : "no",
|
||||
evidence.displayTitleZh ?? finding.displayTitleZh ?? "-",
|
||||
short(evidence.summary ?? finding.summary ?? "-"),
|
||||
]]),
|
||||
"",
|
||||
table(["OTEL_STATUS", "TRACE_REFS", "API", "LINK"], [[
|
||||
otel.status ?? "-",
|
||||
Array.isArray(detail.traceRefs) ? detail.traceRefs.length : 0,
|
||||
links.apiPath ?? "-",
|
||||
links.canonicalPath ?? "-",
|
||||
]]),
|
||||
"",
|
||||
"EVIDENCE",
|
||||
` rootCause=${evidence.rootCause ?? "-"} status=${evidence.rootCauseStatus ?? "-"}`,
|
||||
` evidence=${evidence.evidenceSummary ?? "-"}`,
|
||||
"",
|
||||
"NEXT",
|
||||
` json: bun scripts/cli.ts web-probe sentinel error get --node ${result.node} --lane ${result.lane} --sentinel ${result.sentinelId} --error-id ${body.errorId ?? identity.errorId ?? "-"} --raw`,
|
||||
"",
|
||||
"DISCLOSURE",
|
||||
" error get reads one bounded sentinel error detail by stable errorId and performs backend-controlled OTel lookup when an OTel trace id is present.",
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user