Node.js中Axios GET请求失败(400)致服务器崩溃的问题求助
问题分析与解决方案
你的服务器崩溃是因为axios默认会对非2xx状态码抛出异常,当GET请求返回400时,代码直接抛出未被捕获的错误,而调用这个函数的socket.io异步回调里也没有处理异常,最终导致服务器进程崩溃。
原代码里的if (response.status >= 200 && response.status < 300)根本不会执行——因为axios在收到400状态码时已经抛出错误,代码流程被中断了。
修复方案一:捕获请求异常(推荐)
在findOrCreateDocument里用try/catch包裹GET请求,捕获到异常后执行创建逻辑:
async function findOrCreateDocument(id) { if (id == null) return; try { const response = await axios.get(api + `/${id}`); return response.data; } catch (error) { // 仅当是400(资源不存在)时才创建,也可根据实际错误类型调整判断逻辑 if (error.response?.status === 400) { const response = await axios.post(api, { id: id, data: defaultValue }); return response.data; } // 其他错误重新抛出,让上层处理 throw error; } }
修复方案二:修改axios的状态码验证规则
如果你希望axios不把400视为错误,可以配置validateStatus选项,让所有状态码都被视为成功响应:
async function findOrCreateDocument(id) { if (id == null) return; let response = await axios.get(api + `/${id}`, { validateStatus: (status) => true // 所有状态码都返回成功响应 }); if (response.status >= 200 && response.status < 300) { return response.data; } else if (response.status === 400) { response = await axios.post(api, { id: id, data: defaultValue }); return response.data; } else { // 其他异常状态码抛出错误 throw new Error(`Unexpected status code: ${response.status}`); } }
额外注意:处理上层调用的异常
即使修复了findOrCreateDocument,也要确保调用它的socket.io回调能处理可能的错误,避免单个连接的错误导致整个服务器崩溃:
io.on("connection", (socket) => { socket.on("join-document", async (documentId) => { try { const document = await findOrCreateDocument(documentId); if (!document) { socket.emit("error", "Invalid document ID"); return; } socket.join(documentId); socket.emit("load-document", document.data); socket.on("send-text-change", (delta) => { socket.broadcast.to(documentId).emit("recieve-text-change", delta); }); } catch (error) { console.error("Failed to handle join-document:", error); socket.emit("error", "Failed to load document"); } }); // ...其他逻辑 });
内容的提问来源于stack exchange,提问作者lcm5506
相关产品推荐
相关产品推荐

