mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-22 10:25:20 -06:00
fix(normalization-core): preserve non-Error object causes with extra keys in formatErrorMessage (#126654)
* fix(normalization-core): preserve non-Error object causes with extra keys
The cause-chain branch of formatErrorMessage called only
formatStatusAndCode(cause) with no stringifyUnknown fallback, while the
top-level branch used formatStatusAndCode(value) ?? stringifyUnknown(value).
formatStatusAndCode returns undefined for any object whose keys are not
exactly status/code, so a non-Error object cause carrying extra keys (e.g.
{ statusCode: 429 } or { status: 503, code: "UNAVAILABLE", requestId: "abc" })
was silently dropped — appendCauseMessage(undefined) no-op'd and the loop
broke, losing the diagnostic/retryable detail.
Mirror the top-level branch: appendCauseMessage(formatStatusAndCode(cause) ??
stringifyUnknown(cause)). Behavior-neutral for causes that already render;
restores the dropped detail for the asymmetric case. stringifyUnknown is a
local helper in the same file.
Closes #126652
Co-Authored-By: Claude <noreply@anthropic.com>
* test(normalization-core): assert structured cause metadata
---------
Co-authored-by: ruel225 <ruel225@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Altay <altay@hey.com>
This commit is contained in:
@@ -55,9 +55,21 @@ describe("formatErrorMessage", () => {
|
||||
expect(format(new Error("request failed", { cause: { status: 429 } }))).toBe(
|
||||
"request failed | status=429 code=unknown",
|
||||
);
|
||||
// A non-Error cause carrying recognized status/code fields alongside extra
|
||||
// keys used to be dropped entirely: formatStatusAndCode returns undefined
|
||||
// for any object with keys beyond status/code, and the cause-chain branch
|
||||
// had no stringifyUnknown fallback (unlike the top-level branch). The
|
||||
// structured detail now survives instead of being swallowed.
|
||||
expect(format(new Error("request failed", { cause: { statusCode: 429 } }))).toBe(
|
||||
"request failed",
|
||||
'request failed | {"statusCode":429}',
|
||||
);
|
||||
expect(
|
||||
format(
|
||||
new Error("request failed", {
|
||||
cause: { status: 503, code: "UNAVAILABLE", requestId: "abc" },
|
||||
}),
|
||||
),
|
||||
).toBe('request failed | {"status":503,"code":"UNAVAILABLE","requestId":"abc"}');
|
||||
});
|
||||
|
||||
it("stringifies primitives and circular records without throwing", () => {
|
||||
|
||||
@@ -117,7 +117,10 @@ export function formatErrorMessage(value: unknown, options: FormatErrorMessageOp
|
||||
appendCauseMessage(cause);
|
||||
break;
|
||||
} else {
|
||||
appendCauseMessage(formatStatusAndCode(cause));
|
||||
// Mirror the top-level branch: an object cause with keys beyond
|
||||
// status/code makes formatStatusAndCode return undefined, so fall
|
||||
// back to stringifyUnknown rather than dropping the cause entirely.
|
||||
appendCauseMessage(formatStatusAndCode(cause) ?? stringifyUnknown(cause));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user