Javascript 尝试捕获节点套接字中不工作的信息。io侦听器

Javascript 尝试捕获节点套接字中不工作的信息。io侦听器,javascript,node.js,typescript,websocket,Javascript,Node.js,Typescript,Websocket,我正在开发一款使用WebSocket的应用程序。我将以下代码作为应用程序的一部分: io.on('connection', socket => { let PLAYER = {}; // Listener for event 1 // Listener for event 2 // ... socket.on('setName', ({name, role, room}) => { PLAYER.name = name;

我正在开发一款使用WebSocket的应用程序。我将以下代码作为应用程序的一部分:

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
函数确实抛出错误时,节点就会崩溃,出现以下异常:

events.js:306
    throw err; // Unhandled 'error' event
    ^

Error [ERR_UNHANDLED_ERROR]: Unhandled error. ('error message')
从不发出
错误
事件。是什么导致try-catch块失败的

注意:我使用的是TypeScript,但是在上面的代码段中删除了类型声明,因为它们与问题无关

编辑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!');
    });
}

条长度
大于14时,应用程序会因上述相同错误而崩溃。

我注意到您没有初始化
播放器
变量

let PLAYER = {};
#编辑1:

还可以尝试为套接字服务器添加一个错误处理程序,并记录它,以了解导致错误的原因

socket.on('error', (error) => {
  console.log(error);
});

在本地计算机上复制服务器后,我意识到您正在调用
emit
,调用的是
socket.io
的保留关键字。当您调用
socket.emit('error',e.message)
时,应该存在一个侦听器。像这样的人:

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) => {
  return new Promise((resolve, reject)=>{
    if(bar.length > 14){
      // throw Error('word is too long!');
      reject('word is too long!')
    } else {
      resolve('app did not crash!')
    }
  });  
}

io.on('connection', socket => {
  console.log('new socket connection');
  socket.on('foo', ({bar}) => {
    checkLength(bar).then((result) => {
        console.log('app did not crash!');
    }).catch(err => {
      console.log("app did crash with this error:", err);
    });
  });
}
socket.on('error',err=>{ //发生了一个错误。 }) 您应该为您的
emit
使用不同的短语。我个人在套接字服务器上使用
oops
socket.emit('oops',{error})
。您可以阅读更多有关其上错误处理的信息


要添加,
socket.emit('error')
不会将错误或任何数据传递给客户端,而是由服务器处理,这就是为什么您需要使用不同的短语。

您可以使用promisses,然后可以从then()方法中获益,该方法还返回承诺。它最多包含两个参数:用于承诺成功和失败案例的回调函数

所以你的代码应该是这样的:

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) => {
  return new Promise((resolve, reject)=>{
    if(bar.length > 14){
      // throw Error('word is too long!');
      reject('word is too long!')
    } else {
      resolve('app did not crash!')
    }
  });  
}

io.on('connection', socket => {
  console.log('new socket connection');
  socket.on('foo', ({bar}) => {
    checkLength(bar).then((result) => {
        console.log('app did not crash!');
    }).catch(err => {
      console.log("app did crash with this error:", err);
    });
  });
}

在.on事件上是否可能缺少catch语句?例如io.on('connection',socket=>{}).catch((err)=>{})?。您正在使用哪个websocket库?@Phobos我正在使用socket.io。我没有io.on('connection')事件的catch语句,但是在我正在侦听的其他事件中尝试catch块可以工作-只是没有这个,这很奇怪。@Phobos在方法上的
本身没有错误处理。如果
joinRoom
调用的
async
函数未被
await
-ed,则可能会出现问题。如果
Promise
async
函数出现错误,则无法使用递归
try catch
块捕获,除非
await
完成。我同意@Mike,
joinRoom
可能是一个异步函数,因此您需要使用
joinRoom()捕获错误。catchError(error=>/*此处处理错误*/)
。非常感谢。尽管如此,这个问题一直在我们眼前。我已经添加了我的答案。我在代码中添加了答案,并且在删除
PLAYER
的类型声明时意外地取消了初始化。刚刚在我的帖子中修复了它-我的错!