cloudflare / cloudflare/capnweb
native Promise accepted by types but not serializable at runtime
- Dominant language
- TypeScript
- Stars
- 4k
- Forks
- 143
- Avg merge
- 4d 6h
- Merged PRs (30d)
- 7
Description
When passing native promises in a stub call, a `TypeError: Cannot serialize value: [object Promise]` runtime error is thrown. No ts error is given.
~~It is unclear whether native promises are intended to be supported or not, since~~ a comment in `types.d.ts` mentions all promises, even though the current library throws an error on native promises:
https://github.com/cloudflare/capnweb/blob/686da4465b0f42b4f2a30ba93c2b52424a67ba0b/src/types.d.ts#L124-L125
So depending on what is intended, this issue is either:
1. a runtime bug, where it is not actually resolving promises before delivery
2. ~~or a ts typing bug~~
~~Are all promises supposed to be resolved by the library internally? Or does this library only handle `RpcPromise`?~~
*Edit: It was [confirmed here](https://github.com/cloudflare/capnweb/pull/142#issuecomment-4019184849) that it is a missing feature that will be worked on.*
Here is a reproduction of the issue:
```ts
import { RpcPromise, RpcTarget, newMessagePortRpcSession } from "capnweb";
class MyApi extends RpcTarget {
sayHello(): string {
return 'hello'
}
formatMessage(message: string): string {
return `server received: ${message}`;
}
formatObject(obj: Record): string {
let result = 'server received object with keys:\n';
for (const key in obj) {
result += `- ${key}: ${obj[key]}\n`;
}
return result;
}
}
async function main() {
const channel = new MessageChannel();
newMessagePortRpcSession(channel.port1, new MyApi());
const api = newMessagePortRpcSession(channel.port2);
const pipelinedHello: RpcPromise = api.sayHello();
const out1 = api.formatMessage(pipelinedHello);
const out2 = api.formatMessage(api.sayHello());
const out3 = api.formatObject({
greeting: pipelinedHello,
direct: api.sayHello(),
formatted: out2,
static: 'static value',
});
console.log(await out1); // success
console.log(await out2); // success
console.log(await out3); // success
const nativePromise = Promise.resolve(pipelinedHello);
// no ts error given below, but these are actually runtime errors because native Promise values aren't serializable by capnweb
// and aren't automatically resolved like RpcPromise values are.
api.formatMessage(nativePromise); // throws TypeError: Cannot serialize value: [object Promise]
api.formatMessage(Promise.resolve("not actually transportable")); // throws TypeError: Cannot serialize value: [object Promise]
api.formatObject({
validKey: pipelinedHello,
invalidKey: Promise.resolve("not transportable")
}) // throws TypeError: Cannot serialize value: [object Promise]
}
main();
```
Contributor guide
Assessment
This issue has not been assessed yet.