Node pg返回PostgreSQL主键时出现UnhandledPromiseRejectionWarning问题
问题:返回league_id时触发HTTP无效状态码错误
我用Node pg编写了异步函数getLeagueId查询PostgreSQL数据库中的联赛信息,返回整行数据或name字段时结果正常,但返回league_id主键时,会触发UnhandledPromiseRejectionWarning及HTTP无效状态码错误,更换postgres.js库也存在同样问题。
代码示例
getLeagueId = async (league_name) => { // Return the league id from a given league const client = this.connectToDatabase(); await client.connect(); try { const query = await client.query(`SELECT * FROM leagues WHERE name = '${league_name}';`); await client.end(); return query.rows[0]; } catch (err) { console.log(`An error occurred when fetching league ID: ${err}`); } };
返回整行数据结果
{"league_id":1,"name":"Premier League","type":"League","country":"England","logo":"https://media-3.api-sports.io/football/leagues/39.png","flag":"https://media-1.api-sports.io/flags/gb.svg"}
返回league_id时的报错信息
express deprecated res.send(status): Use res.sendStatus(status) instead app.js:52:11 (node:274778) UnhandledPromiseRejectionWarning: RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 1 at ServerResponse.writeHead (_http_server.js:248:11) at ServerResponse._implicitHeader (_http_server.js:239:8) at write_ (_http_outgoing.js:654:9) at ServerResponse.end (_http_outgoing.js:766:5) at ServerResponse.send (/home/stoffel/Documents/dailySports/node_modules/express/lib/response.js:232:10) at ServerResponse.json (/home/stoffel/Documents/dailySports/node_modules/express/lib/response.js:278:15) at ServerResponse.send (/home/stoffel/Documents/dailySports/node_modules/express/lib/response.js:162:21) at /home/stoffel/Documents/dailySports/app.js:55:11 at processTicksAndRejections (internal/process/task_queues.js:97:5) (node:274778) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:274778) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
问题原因
报错核心是Invalid status code: 1:你在Express响应中直接将league_id(值为1)传给了res.send(),而Express会把纯数字参数识别为HTTP状态码,但1不属于合法的HTTP状态码范围(合法状态码为100-599),因此触发错误。
比如你可能写了类似这样的路由代码:
app.get('/league', async (req, res) => { const league = await getLeagueId('Premier League'); res.send(league.league_id); // 直接传数字1,被Express当成状态码 });
解决办法
将数字包装为对象或字符串返回
让Express识别为响应体而非状态码:// 包装成JSON对象 res.send({ league_id: league.league_id }); // 或转换为字符串 res.send(String(league.league_id));使用
res.json()明确返回JSON格式res.json()会正确处理单个数值,不会被误判为状态码:res.json(league.league_id);补全Promise错误捕获
UnhandledPromiseRejectionWarning是因为异步路由未捕获错误,需在路由中添加try/catch:app.get('/league', async (req, res) => { try { const league = await getLeagueId('Premier League'); res.json(league.league_id); } catch (err) { res.status(500).send('服务器查询出错'); } });修复SQL注入风险
原代码用字符串拼接生成SQL,存在注入漏洞,改用参数化查询:const query = await client.query(`SELECT * FROM leagues WHERE name = $1;`, [league_name]);
内容的提问来源于stack exchange,提问作者Christoff Van Der Walt
相关产品推荐
相关产品推荐

