fix: preserve error subtype through serialize#26
Conversation
|
a few things not ideal:
Accordingly, I would rather use |
`typeOf` derived the serialized error `name` from
`Object.prototype.toString`, whose tag is `Error` for every native error
subtype, so `TypeError`, `RangeError`, `SyntaxError`, `ReferenceError`,
`EvalError` and `URIError` all serialized as `{name: "Error"}` and revived
as a plain `Error`:
deserialize(serialize(new TypeError('x'))) instanceof TypeError; // false
Native `structuredClone` keeps the subtype, and the deserializer already
rebuilds the right constructor when handed the correct name.
Use the instance `name` when it is one of the standard error names,
otherwise `Error` — matching `structuredClone`, which also normalizes
custom and aggregate errors to `Error`.
4256e56 to
9f67bfa
Compare
|
Done. Switched to On the exact form: I kept the |
|
@spokodev it's up and running |
typeOfbuilds the serialized errornamefromObject.prototype.toString.call(value), whose tag isErrorfor every native error subtype. SoTypeError,RangeError,SyntaxError,ReferenceError,EvalErrorandURIErrorare all serialized as{name: "Error"}and come back as a plainError:Native
structuredClonepreserves the subtype, and the deserializer here already rebuilds the correct constructor vianew env[name]once it is given the right name — it just never was, so the type was lost on every round-trip.The fix reads the instance
nameand keeps it when it is one of the seven standard error names, otherwise falls back toError. That matchesstructuredClone, which normalizes custom subclasses andAggregateErrortoErroras well, and it keeps the deserializer safe since those seven names are always constructable globals.Plain
Errorserialization is unchanged, so existing output is unaffected. Added a round-trip test over all seven subtypes; reverting theserialize.jschange makes it fail.