You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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当成状态码
});

解决办法

  1. 将数字包装为对象或字符串返回
    让Express识别为响应体而非状态码:

    // 包装成JSON对象
    res.send({ league_id: league.league_id });
    // 或转换为字符串
    res.send(String(league.league_id));
    
  2. 使用res.json()明确返回JSON格式
    res.json()会正确处理单个数值,不会被误判为状态码:

    res.json(league.league_id);
    
  3. 补全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('服务器查询出错');
      }
    });
    
  4. 修复SQL注入风险
    原代码用字符串拼接生成SQL,存在注入漏洞,改用参数化查询:

    const query = await client.query(`SELECT * FROM leagues WHERE name = $1;`, [league_name]);
    

内容的提问来源于stack exchange,提问作者Christoff Van Der Walt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 17:17:49