@@ -52,4 +52,38 @@ describe('devtools rpc', () => {
5252
5353 expect ( await server . broadcast . $call ( 'hey' , 'server' ) ) . toEqual ( expect . arrayContaining ( [ 'hey server, I\'m client 1' , 'hey server, I\'m client 2' ] ) )
5454 } )
55+
56+ // Regression: a `jsonSerializable: true` RPC that throws used to crash the
57+ // WS serializer with DF0020 because the error envelope was strict-JSON-encoded
58+ // alongside the result path.
59+ it ( 'returns a rejection (not a serialization crash) when a jsonSerializable RPC throws' , async ( ) => {
60+ const PORT = 3334
61+ const HOST = '127.0.0.1'
62+ const WS_URL = `ws://${ HOST } :${ PORT } `
63+
64+ const serverFunctions = {
65+ explode : async ( ) => {
66+ throw new Error ( 'boom' )
67+ } ,
68+ }
69+
70+ const definitions = new Map < string , { jsonSerializable ?: boolean } > ( [
71+ [ 'explode' , { jsonSerializable : true } ] ,
72+ ] )
73+
74+ const server = createRpcServer < Record < string , never > , typeof serverFunctions > ( serverFunctions )
75+ const { wss } = attachWsRpcTransport ( server , { port : PORT , host : HOST , definitions : definitions as any } )
76+
77+ try {
78+ const client = createRpcClient < typeof serverFunctions , Record < string , never > > ( { } , {
79+ channel : createWsRpcChannel ( { url : WS_URL , definitions : definitions as any } ) ,
80+ } )
81+
82+ await expect ( client . $call ( 'explode' ) ) . rejects . toThrow ( / b o o m / )
83+ }
84+ finally {
85+ for ( const c of wss . clients ) c . terminate ( )
86+ await new Promise < void > ( resolve => wss . close ( ( ) => resolve ( ) ) )
87+ }
88+ } )
5589} )
0 commit comments