Convert an arbitrary console-arg list (strings, numbers, booleans,
objects, null, undefined) into a single space-separated display
string. Used both for the user-visible row content and as the
filter haystack — keeping the same output for both means the
"filter by visible text" promise holds.
Objects are pretty-printed with JSON.stringify(_, null, 2). If
stringify throws (e.g. a circular reference), falls back to the
value's string representation without allowing a hostile toString to escape.
Error (and DOMException) is checked FIRST, before the object branch:
name / message / stack are non-enumerable, so JSON.stringify(err) is
"{}" — and the catch → String(arg) fallback never fires, because
stringify succeeds at producing that empty object. Every log.*(…, error)
call site therefore lost its message here, which is exactly what made a real
bug report read OPFSStore metadata save failed {}. Ordering matters beyond
plain Errors too: a subclass that assigns own enumerable fields (LoaderError
sets name/cause) stringifies to a non-empty but still message-LESS object.
KEEP IN LOCKSTEP with debug-console.ts::formatArgAsDOMElement, which renders
the same values into DOM. The two must agree for Errors or the visible row and
the copied text disagree. (They differ for plain strings by design — the DOM
renderer quotes them.)
Convert an arbitrary console-arg list (strings, numbers, booleans, objects, null, undefined) into a single space-separated display string. Used both for the user-visible row content and as the filter haystack — keeping the same output for both means the "filter by visible text" promise holds.
Objects are pretty-printed with
JSON.stringify(_, null, 2). If stringify throws (e.g. a circular reference), falls back to the value's string representation without allowing a hostiletoStringto escape.Error(andDOMException) is checked FIRST, before the object branch:name/message/stackare non-enumerable, soJSON.stringify(err)is"{}"— and thecatch → String(arg)fallback never fires, because stringify succeeds at producing that empty object. Everylog.*(…, error)call site therefore lost its message here, which is exactly what made a real bug report readOPFSStore metadata save failed {}. Ordering matters beyond plain Errors too: a subclass that assigns own enumerable fields (LoaderErrorsetsname/cause) stringifies to a non-empty but still message-LESS object.KEEP IN LOCKSTEP with
debug-console.ts::formatArgAsDOMElement, which renders the same values into DOM. The two must agree for Errors or the visible row and the copied text disagree. (They differ for plain strings by design — the DOM renderer quotes them.)