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

请求协助排查iTunes电影接口请求中的UnhandledPromiseRejectionWarning错误

解决Node.js+Express中iTunes接口请求的UnhandledPromiseRejectionWarning问题

我帮你排查到几个导致这个UnhandledPromiseRejectionWarning的核心问题,咱们一步步来修复:

问题根源分析

  1. 无论请求成功与否都会抛出错误:你的代码在if (movieResult.status == 200)块渲染页面后,依然执行了throw new Error(movieResult.status);——哪怕状态码是200,这会强制拒绝Promise,而你没有任何catch逻辑处理这个拒绝,所以触发了警告。
  2. 缺少异步错误捕获机制:异步路由中的await操作(fetch、json解析)可能抛出网络错误、解析错误,但你没有用try/catch包裹这些操作,无法捕获这类异常。
  3. 单个电影路由的索引处理不当:req.params.id是字符串类型,直接作为数组索引可能引发隐式转换问题,而且没有判断索引是否在有效范围内,容易导致渲染时出现undefined。

修复后的完整代码

const fetch = require('node-fetch');

module.exports = function (app) {
  // Get homepage
  app.get('/', async (req, res) => {
    try {
      const url = 'https://itunes.apple.com/us/rss/topmovies/limit=20/json';
      const movieResult = await fetch(url);

      // 先判断请求是否成功,失败则抛出错误
      if (!movieResult.ok) {
        throw new Error(`请求失败:${movieResult.status} ${movieResult.statusText}`);
      }

      const movieJson = await movieResult.json();
      const movieToRender = movieJson.feed.entry;
      res.render('home', { movies: movieToRender });
    } catch (err) {
      // 统一处理所有异步错误,返回500或者自定义错误页面
      console.error('首页加载失败:', err);
      res.status(500).send('加载热门电影列表失败,请稍后重试');
    }
  });

  // Get route for each specific movie
  app.get('/movie/:id', async (req, res) => {
    try {
      const url = 'https://itunes.apple.com/us/rss/topmovies/limit=20/json';
      // 将字符串id转为数字,确保是有效的数组索引
      const movieIndex = parseInt(req.params.id, 10);
      const movieResult = await fetch(url);

      if (!movieResult.ok) {
        throw new Error(`请求失败:${movieResult.status} ${movieResult.statusText}`);
      }

      const movieJson = await movieResult.json();
      const movieList = movieJson.feed.entry;
      // 检查索引是否在有效范围内
      if (isNaN(movieIndex) || movieIndex < 0 || movieIndex >= movieList.length) {
        return res.status(404).send('找不到指定的电影');
      }

      const movieToRender = movieList[movieIndex];
      res.render('modal', { movie: movieToRender });
    } catch (err) {
      console.error('单个电影加载失败:', err);
      res.status(500).send('加载电影详情失败,请稍后重试');
    }
  });
};

关键修改点说明

  • 添加try/catch块:所有异步操作都包裹在try里,catch块统一处理错误,避免未处理的Promise拒绝。
  • 调整错误触发逻辑:只有当movieResult.ok为false(即状态码不在200-299范围内)时才抛出错误,成功时直接渲染页面,不再执行throw。
  • 处理电影索引:将req.params.id转为整数,并检查是否为有效索引,避免因无效索引导致的渲染错误,同时返回404状态码提示用户。
  • 完善错误信息:抛出错误时包含状态码和状态文本,方便调试;错误处理时返回对应的HTTP状态码和友好提示。

内容的提问来源于stack exchange,提问作者JeffreyC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:06:27