如何处理Node.js中用户输入错误与Socket连接异常
Node.js Net Socket 连接错误处理问题
问题描述
我正在创建一个接受用户输入参数的Socket客户端,由于用户输入难免存在错误,需要处理Socket无法连接到指定Address:Port组合的情况。
使用Node.js的net API创建客户端Socket连接到服务器,编写了支持用户输入的连接函数:
function createConnection(HOST,PORT){ let socket = new net.Socket(); socket.connect(PORT, HOST, function() { console.log('CONNECTED TO: ' + HOST + ':' + PORT); socket.write(SomeData) } socket.on("data", (data) => { console.log("data") }) socket.on("error", (err) => { console.log(err," This Error Occured!") }) socket.on("close", () => { console.log("Closing Connection") }) }
调用该函数传入用户定义的参数时,无论用try/catch包裹调用:
try{ createConnection(userInputedHost, userInputedPort) } catch (error) { console.log(error, "This Error Occured!") }
还是在Socket创建时绑定error事件,都无法看到自定义的"This Error Occured!"提示,反而控制台输出默认异常:
node:events:505 throw er; // Unhandled 'error' event ^ Error: connect ECONNREFUSED 127.0.0.1:3977 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16) Emitted 'error' event on Socket instance at: at emitErrorNT (node:internal/streams/destroy:157:8) at emitErrorCloseNT (node:internal/streams/destroy:122:3) at processTicksAndRejections (node:internal/process/task_queues:83:21) { errno: -4078, code: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 3977 }
请问我是否正确使用了try/catch?是否误解了net API的error事件?有没有办法处理连接失败请求而不导致Node应用崩溃?
解决方案
1. try/catch无法捕获错误的原因
你用的try/catch无法捕获异步操作抛出的错误。socket.connect是异步方法,它的错误不会在调用createConnection的同步上下文里抛出,而是会在事件循环的后续阶段触发error事件,所以try/catch抓不到这些错误。
2. error事件绑定的问题
你的代码存在两个关键问题:
- 语法错误:
socket.connect的调用缺少闭合的),这会导致代码执行出错,后续的error事件绑定代码可能根本没执行到。 - 事件绑定时机错误:你先调用了
socket.connect,之后才绑定error事件。如果连接失败的事件在error事件监听器绑定之前就触发了,就会变成未处理的error事件,导致Node应用崩溃。
3. 正确的错误处理写法
修正后的代码应该先绑定error事件,再调用connect,同时修复语法错误:
function createConnection(HOST, PORT) { let socket = new net.Socket(); // 先绑定error事件,再执行connect socket.on("error", (err) => { console.log(err, " This Error Occured!"); // 可以在这里关闭socket或者做其他清理操作 socket.destroy(); }); socket.on("data", (data) => { console.log(data.toString()); }); socket.on("close", () => { console.log("Closing Connection"); }); // 修复语法错误:补上闭合括号 socket.connect(PORT, HOST, function() { console.log('CONNECTED TO: ' + HOST + ':' + PORT); socket.write(SomeData); // 确保SomeData已定义 }); }
这样修改后,连接失败时error事件监听器会正确捕获错误,输出你自定义的提示,同时不会导致应用崩溃。
额外说明:Promise风格封装
如果需要用Promise风格处理异步操作,也可以封装成Promise:
function createConnection(HOST, PORT) { return new Promise((resolve, reject) => { let socket = new net.Socket(); socket.on("error", (err) => { reject(err); socket.destroy(); }); socket.on("connect", () => { resolve(socket); console.log('CONNECTED TO: ' + HOST + ':' + PORT); socket.write(SomeData); }); socket.on("data", (data) => { console.log(data.toString()); }); socket.on("close", () => { console.log("Closing Connection"); }); socket.connect(PORT, HOST); }); } // 使用方式 createConnection(userInputedHost, userInputedPort) .then(socket => { // 连接成功后的操作 }) .catch(error => { console.log(error, " This Error Occured!"); });
这样就可以用.catch来捕获连接错误,同时保持代码的异步风格。
内容的提问来源于stack exchange,提问作者Eric Olsen
相关产品推荐
相关产品推荐

