Skip to content

Preserve own properties of Error instances across serialization/deserialization#166

Merged
kentonv merged 2 commits intocloudflare:mainfrom
aron-cf:error-attributes
May 8, 2026
Merged

Preserve own properties of Error instances across serialization/deserialization#166
kentonv merged 2 commits intocloudflare:mainfrom
aron-cf:error-attributes

Conversation

@aron-cf
Copy link
Copy Markdown
Contributor

@aron-cf aron-cf commented Apr 30, 2026

Closes #87.

Today the wire format for Error only carries name, message, and (optionally) stack. Anything a user attaches to the error — code, details, a cause, the inner errors of an AggregateError — is lost the moment the error crosses an RPC boundary.

This PR extends the error expression with an optional fifth element, props. This uses the same serialization/deserialization as any other object.

Error.cause and AggregateError.errors are normally non-enumerable, so they are picked up explicitly by the encoder. On the receive side, the decoder constructs the error as before and then assigns each entry from props as an own enumerable property on the result.

let err = new Error("rate limited");
err.code = "E_LIMIT";
err.retryAfter = 30;
throw err;
// receiver sees: err.code === "E_LIMIT", err.retryAfter === 30

Properties that cannot be fully serialized are dropped.

Tests have been added to verify the serialization/deserialization of various different error cases and failure modes. There may be too many, happy to remove any if needed.

The error expression in protocol.md now documents the optional props element, the lossy-fallback semantics.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 30, 2026

🦋 Changeset detected

Latest commit: 9025285

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
capnweb Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 30, 2026

Open in StackBlitz

npm i https://pkg.pr.new/cloudflare/capnweb@166

commit: 9025285

Comment thread .changeset/error-own-properties.md Outdated
Comment thread src/serialize.ts Outdated
Comment thread protocol.md Outdated
@aron-cf aron-cf marked this pull request as ready for review April 30, 2026 10:27
Comment thread src/serialize.ts
Comment thread src/serialize.ts
Comment thread src/serialize.ts
Comment thread __tests__/index.test.ts
Comment thread .changeset/error-own-properties.md Outdated
Comment thread src/serialize.ts Outdated
Comment thread src/serialize.ts Outdated
Comment thread src/serialize.ts
Comment thread protocol.md Outdated
@aron-cf aron-cf force-pushed the error-attributes branch from 9d31281 to 49cb3fd Compare May 8, 2026 10:48
Copy link
Copy Markdown
Contributor Author

@aron-cf aron-cf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reworked the code to skip any error properties that fail to serialize. I've done this in a pre-scan pass (that early exits when it hits a negative) rather than attempting to recover from a serialization error, from what I understand this removes the risk of leaking ReadableStreams at the cost of two passes. Let me know your thoughts.

Comment thread src/serialize.ts
Comment thread src/serialize.ts Outdated
Comment thread protocol.md Outdated
Comment thread src/serialize.ts Outdated
Comment thread .changeset/error-own-properties.md Outdated
@aron-cf aron-cf force-pushed the error-attributes branch from 49cb3fd to af2e7f3 Compare May 8, 2026 10:57
This commit ensures that own properties are sent across the RPC
boundary and reconstructed on the Error instance on the other side.

The `cause` field and, in the case of `errors` for `AggregateError`
are also copied over.
@aron-cf aron-cf force-pushed the error-attributes branch from af2e7f3 to 06cd6a7 Compare May 8, 2026 11:03
@aron-cf aron-cf requested a review from kentonv May 8, 2026 11:05
@kentonv kentonv merged commit 7413e43 into cloudflare:main May 8, 2026
5 checks passed
@github-actions github-actions Bot mentioned this pull request May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom error details

2 participants