【发布时间】:2021-01-01 20:13:03
【问题描述】:
我正在开发一个涉及使用 WebSockets 的应用程序。我有以下代码作为应用程序的一部分:
io.on('connection', socket => {
let PLAYER = {};
// Listener for event 1
// Listener for event 2
// ...
socket.on('setName', ({name, role, room}) => {
PLAYER.name = name;
PLAYER.role = role;
PLAYER.room = room;
try{
joinRoom(PLAYER); // This function can throw an error
socket.emit('roomJoin');
}catch(e){
socket.emit('error', e.message);
return;
}
});
});
现在,当 joinRoom 函数确实抛出错误时,Node 会崩溃并出现以下异常:
events.js:306
throw err; // Unhandled 'error' event
^
Error [ERR_UNHANDLED_ERROR]: Unhandled error. ('error message')
error 事件永远不会发出。是什么导致 try catch 块失败?
注意:我使用的是 TypeScript,但已删除上述 sn-p 中的类型声明,因为它们与问题无关。
编辑 1:
我用更简单的代码重新创建了这个问题,如下所示:
import express from 'express';
import socketio from 'socket.io';
import http from 'http';
const PORT = process.env.PORT || 8000;
const app = express();
const server = http.createServer(app);
const io = socketio(server);
server.listen(PORT, () => {
console.log(`Listening on port ${PORT}`);
});
const checkLength = (bar) => {
if(bar.length > 14){
throw Error('word is too long!');
}
// ...
}
io.on('connection', socket => {
console.log('new socket connection');
socket.on('foo', ({bar}) => {
try{
checkLength(bar);
}catch(e){
socket.emit('error', e.message);
return;
}
console.log('app did not crash!');
});
}
bar 的长度大于 14 时,应用会崩溃并出现上述相同的错误。
【问题讨论】:
-
您是否可能缺少关于 .on 事件的 catch 语句? IE。 io.on('connection', socket => {}).catch((err) => {}) ?.您使用的是哪个 websocket 库?
-
@Phobos 我正在使用 socket.io。我没有针对 io.on('connection') 事件的 catch 语句,但是我正在监听的其他事件中的 try-catch 块有效 - 只是不是这个,这很奇怪。
-
@Phobos
on方法本身没有错误处理。如果joinRoom正在调用不是await-ed 的async函数,则可能存在问题。如果Promise或async函数出错,则不能用常规try-catch块捕获,除非完成await。 -
我同意@Mike,
joinRoom可能是一个异步函数,因此您需要使用joinRoom().catchError(error => /* handle error here */)来捕获错误。 -
非常感谢。虽然,这个问题一直都在我们眼前。我已经添加了我的答案。
标签: javascript node.js typescript websocket