fix: improve hwlab probe diagnostics
This commit is contained in:
@@ -1773,7 +1773,7 @@ function sanitize(value, depth = 0, seen = new WeakSet()) {
|
||||
if (typeof value === "number" || typeof value === "boolean") return value;
|
||||
if (typeof value === "bigint") return String(value);
|
||||
if (typeof value === "function" || typeof value === "symbol") return "[" + typeof value + "]";
|
||||
if (depth > 8) return "[max-depth]";
|
||||
if (depth > 12) return "[max-depth]";
|
||||
if (Array.isArray(value)) return value.slice(0, 200).map((item) => sanitize(item, depth + 1, seen));
|
||||
if (typeof value === "object") {
|
||||
if (seen.has(value)) return "[circular]";
|
||||
@@ -1836,6 +1836,7 @@ async function emit(payload) {
|
||||
}
|
||||
|
||||
function compactStdoutPayload(payload) {
|
||||
const issueEvidence = compactIssueEvidenceForStdout(payload?.summary?.issueEvidence ?? issueEvidenceFromPayload(payload));
|
||||
return {
|
||||
ok: payload?.ok === true,
|
||||
status: payload?.status ?? null,
|
||||
@@ -1859,6 +1860,7 @@ function compactStdoutPayload(payload) {
|
||||
lastScreenshot: compactArtifactForStdout(payload?.lastScreenshot),
|
||||
readiness: compactJsonForStdout(payload?.readiness),
|
||||
artifacts: compactArtifactsForStdout(payload?.artifacts),
|
||||
issueEvidence,
|
||||
summary: compactSummaryForStdout(payload?.summary),
|
||||
safety: {
|
||||
valuesRedacted: true,
|
||||
@@ -1874,7 +1876,7 @@ function compactScriptForStdout(script) {
|
||||
const steps = Array.isArray(value.steps) ? value.steps : [];
|
||||
return {
|
||||
ok: value.ok === true,
|
||||
result: compactJsonForStdout(value.result),
|
||||
result: compactJsonForEvidence(value.result),
|
||||
stepCount: steps.length,
|
||||
};
|
||||
}
|
||||
@@ -1932,6 +1934,7 @@ function compactSummaryForStdout(summary) {
|
||||
apiMatrix: compactApiMatrixForStdout(value.apiMatrix),
|
||||
stepCount: Number.isFinite(value.stepCount) ? value.stepCount : null,
|
||||
lastStep: compactStepForStdout(value.lastStep),
|
||||
issueEvidence: compactIssueEvidenceForStdout(value.issueEvidence),
|
||||
valuesRedacted: true,
|
||||
};
|
||||
}
|
||||
@@ -2000,6 +2003,98 @@ function compactJsonForStdout(value, depth = 0) {
|
||||
return compactText(String(value), 180);
|
||||
}
|
||||
|
||||
function issueEvidenceFromPayload(payload) {
|
||||
const steps = publicSteps();
|
||||
const artifacts = Array.isArray(payload?.artifacts?.items) ? payload.artifacts.items : artifactRecords;
|
||||
const screenshots = artifacts
|
||||
.filter((item) => item && typeof item === "object" && item.kind === "screenshot")
|
||||
.slice(-5)
|
||||
.map((item) => compactArtifactForStdout(item))
|
||||
.filter(Boolean);
|
||||
const ok = payload?.ok === true;
|
||||
const degradedReason = ok ? null : payload?.error ?? payload?.failureKind ?? "web-probe-script-failed";
|
||||
const failureKind = ok ? null : classifyIssueFailureKind(payload?.failureKind ?? payload?.error ?? degradedReason, payload?.errorMessage);
|
||||
const failedCondition = ok ? null : payload?.errorMessage ?? payload?.error ?? payload?.failureKind ?? "script did not pass";
|
||||
const script = payload?.script && typeof payload.script === "object" ? payload.script : {};
|
||||
return {
|
||||
ok,
|
||||
status: payload?.status ?? null,
|
||||
degradedReason,
|
||||
failureKind,
|
||||
failedCondition,
|
||||
nextAction: ok ? null : issueNextAction(failureKind, payload),
|
||||
baseUrl: payload?.baseUrl ?? null,
|
||||
finalUrl: payload?.finalUrl ?? payload?.lastUrl ?? null,
|
||||
lastUrl: payload?.lastUrl ?? payload?.finalUrl ?? null,
|
||||
scriptSha256: payload?.scriptSha256 ?? null,
|
||||
runDir,
|
||||
reportPath: payload?.reportPath ?? null,
|
||||
reportSha256: payload?.reportSha256 ?? null,
|
||||
result: compactJsonForEvidence(script.result),
|
||||
apiMatrix: compactApiMatrixForStdout(latestApiMatrixFromSteps(steps)),
|
||||
lastStep: steps.length > 0 ? compactStepForEvidence(steps[steps.length - 1]) : null,
|
||||
steps: steps.slice(-3).map((step) => compactStepForEvidence(step)),
|
||||
lastScreenshot: compactArtifactForStdout(payload?.lastScreenshot),
|
||||
screenshots,
|
||||
valuesRedacted: true,
|
||||
};
|
||||
}
|
||||
|
||||
function compactIssueEvidenceForStdout(value) {
|
||||
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
||||
return {
|
||||
ok: value.ok === true,
|
||||
status: value.status ?? null,
|
||||
degradedReason: typeof value.degradedReason === "string" ? compactText(value.degradedReason, 600) : value.degradedReason ?? null,
|
||||
failureKind: typeof value.failureKind === "string" ? compactText(value.failureKind, 300) : value.failureKind ?? null,
|
||||
failedCondition: typeof value.failedCondition === "string" ? compactText(value.failedCondition, 1200) : value.failedCondition ?? null,
|
||||
nextAction: typeof value.nextAction === "string" ? compactText(value.nextAction, 1200) : value.nextAction ?? null,
|
||||
baseUrl: value.baseUrl ?? null,
|
||||
finalUrl: value.finalUrl ?? null,
|
||||
lastUrl: value.lastUrl ?? null,
|
||||
scriptSha256: value.scriptSha256 ?? null,
|
||||
runDir: value.runDir ?? runDir,
|
||||
reportPath: value.reportPath ?? null,
|
||||
reportSha256: value.reportSha256 ?? null,
|
||||
result: compactJsonForEvidence(value.result),
|
||||
apiMatrix: compactApiMatrixForStdout(value.apiMatrix),
|
||||
lastStep: compactStepForEvidence(value.lastStep),
|
||||
steps: Array.isArray(value.steps) ? value.steps.slice(-3).map((step) => compactStepForEvidence(step)) : [],
|
||||
lastScreenshot: compactArtifactForStdout(value.lastScreenshot),
|
||||
screenshots: Array.isArray(value.screenshots) ? value.screenshots.slice(-5).map((item) => compactArtifactForStdout(item)).filter(Boolean) : [],
|
||||
valuesRedacted: true,
|
||||
};
|
||||
}
|
||||
|
||||
function compactStepForEvidence(step) {
|
||||
if (!step || typeof step !== "object" || Array.isArray(step)) return null;
|
||||
return {
|
||||
index: Number.isFinite(step.index) ? step.index : null,
|
||||
name: typeof step.name === "string" ? step.name : null,
|
||||
ok: typeof step.ok === "boolean" ? step.ok : null,
|
||||
atMs: Number.isFinite(step.atMs) ? step.atMs : null,
|
||||
data: compactJsonForEvidence(step.data),
|
||||
};
|
||||
}
|
||||
|
||||
function compactJsonForEvidence(value, depth = 0) {
|
||||
if (value === null || value === undefined) return value ?? null;
|
||||
if (typeof value === "string") return compactText(value, 600);
|
||||
if (typeof value === "number" || typeof value === "boolean") return value;
|
||||
if (typeof value === "bigint") return String(value);
|
||||
if (typeof value === "function" || typeof value === "symbol") return "[" + typeof value + "]";
|
||||
if (depth >= 8) return "[max-depth]";
|
||||
if (Array.isArray(value)) return value.slice(0, 16).map((item) => compactJsonForEvidence(item, depth + 1));
|
||||
if (typeof value === "object") {
|
||||
const out = {};
|
||||
for (const [key, nested] of Object.entries(value).slice(0, 32)) {
|
||||
out[key] = compactJsonForEvidence(nested, depth + 1);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return compactText(String(value), 600);
|
||||
}
|
||||
|
||||
function compactText(value, maxChars) {
|
||||
return redactString(String(value)).replace(/\s+/gu, " ").trim().slice(0, maxChars);
|
||||
}
|
||||
@@ -2037,6 +2132,7 @@ function scriptIssueSummary(payload) {
|
||||
apiMatrix,
|
||||
stepCount: stepRecords.length,
|
||||
lastStep: stepRecords.length > 0 ? deepClonePlain(stepRecords[stepRecords.length - 1]) : null,
|
||||
issueEvidence: issueEvidenceFromPayload(payload),
|
||||
valuesRedacted: true,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user