cloudflare / cloudflare/workerd

🐛 Bug Report — Runtime APIs: If WebSocket client close first, will cause workerd has Uncaught (in response) Error

Open
#659 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
8.7k
Forks
739
Avg merge
2d 20h
Merged PRs (30d)
174

Description

Step for this error,

1. Open the WebSocket in worker
2. Use any websocket test client
3. Close WebSocket in the client, below error will throw.

```
workerd/server/server.c++:2347: error: Uncaught exception: workerd/io/io-context.c++:1261: failed: remote.jsg.Error: The script will never generate a response.
stack: 0 0 0 0 7ff71a146272 0 7ff71a146234 0 0 0
workerd/server/server.c++:2259: error: exception = kj/compat/http.c++:2061: failed: expected !inBody; previous HTTP message body incomplete; can't write more messages
stack: 7ff71a138a6f 7ff71a1d035d 7ff71a205121 7ff71a194056 7ff71a1941fb 7ff719fb2e64 7ff71a1b28ca 0 0
-------------close----------------- CloseEvent {
wasClean: undefined,
reason: undefined,
code: undefined
}
An event handler returned a promise that will be ignored. Event handlers should not have a return value and should not be async functions.
X [ERROR] Uncaught (in response) Error: The script will never generate a response.
```

I think this is bug. I even test code from this blog, same errors as long as client close websocket first... https://blog.cloudflare.com/introducing-websockets-in-workers/

But below is my sample code.
```js
export default {
async fetch(request: Request) {
let address = '';
let portWithRandomLog = '';

const log = (info: string, event?: any) => {
console.log(`[${address}:${portWithRandomLog}] ${info}`, event || '');
};

const upgradeHeader = request.headers.get('Upgrade');
if (!upgradeHeader || upgradeHeader !== 'websocket') {
return new Response('Expected Upgrade: websocket', { status: 426 });
}

const webSocketPair = new WebSocketPair();
const [client, webSocket] = Object.values(webSocketPair);
const earlyDataHeader = request.headers.get('sec-websocket-protocol') || '';
webSocket.accept();
webSocket.addEventListener('message', (event) => {
console.log(event.data);
webSocket.send(`server reponse after client sent ${event.data}`);
if (event.data === 'close') {
webSocket.close();
}
});
webSocket.addEventListener('close', async (event) => {
console.log('-------------close-----------------', event);
});

webSocket.addEventListener('error', () => {
console.log('-------------error-----------------');
});

return new Response(null, {
status: 101,
webSocket: client,
});
},
};
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.