workerd
workerd copied to clipboard
🐛 Bug Report — Runtime APIs: If WebSocket client close first, will cause workerd has Uncaught (in response) Error
Step for this error,
- Open the WebSocket in worker
- Use any websocket test client
- 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.
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,
});
},
};