【问题标题】:UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: #) Error: 200UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:#)错误:200
【发布时间】:2018-05-27 07:43:52
【问题描述】:

通过 iTunes 商店运行我的获取请求时 从https://itunes.apple.com/us/rss/topmovies/limit=20/json获取 iTunes 上的热门电影列表

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

module.exports = function (app) {
    //Get homepage
    app.get('/', async (req, res) => {
        const url = 'https://itunes.apple.com/us/rss/topmovies/limit=20/json';
        const movie = req.params.id
        const movieResult = await fetch(url);
        const statusCodeIs200Or300 = movieResult.ok;
        const movieError = movieResult.statusText;
        const movieJson = await movieResult.json();
        const movieToRender = movieJson.feed.entry;
        console.log(movieResult.ok);
        if (movieResult.status == 200) {
          res.render('home', { movies: movieToRender});
        }
        throw new Error(movieResult.status);
    });

    // Get route for each specific the movies
    app.get('/movie/:id', async (req, res) => {
        const url = 'https://itunes.apple.com/us/rss/topmovies/limit=20/json';
        const movie = req.params.id
        const movieResult = await fetch(url)
        const statusCodeIs200Or300 = movieResult.ok
        const movieError = movieResult.statusText
        const movieJson = await movieResult.json()
        const movieToRender = movieJson.feed.entry[movie]
        // if statetement
        if (movieResult.status == 200) {
          res.render('modal', { movie: movieToRender})
        }
        throw new Error(movieResult.status);
    });


}

UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:#)错误:200

请帮我解决这个错误

【问题讨论】:

  • 其中一个承诺似乎有问题

标签: node.js fetch


【解决方案1】:

错误只是说明您没有处理拒绝部分 在正常的承诺中,有 .catch() 部分,如下所示

new Promise(function(resolve, reject) {
  resolve('Success');
  //reject('err)
})
.then(function(value) {
console.log("everything ok")
})
.catch(function(e) {
  console.log(e); // "oh, no!"
})

但是在你异步等待出现错误时会发生什么? 您可以执行以下操作之一

try {
      await  await fetch(url)
    } catch (err) {
      //handle error 
    }

或 也许像这样的中间件

const express = require('express');

const app = express();

app.get('/', safeHandler(handler));

app.listen(3000);

function safeHandler(handler) {
  return function(req, res) {
    handler(req, res).catch(error => res.status(500).send(error.message));
  };
}

async function handler(req, res) {
  await new Promise((resolve, reject) => reject(new Error('Hang!')));
  res.send('Hello, World!');
}

后面的部分由这个来源safe handler solution拍摄

【讨论】:

    【解决方案2】:

    Fadi 的回答解释了如何正确处理承诺的异常,但在您的情况下,您还需要从函数中返回一些内容,否则它总是会抛出错误:

    app.get('/', async (req, res) => {
        const url = 'https://itunes.apple.com/us/rss/topmovies/limit=20/json';
        const movie = req.params.id
        const movieResult = await fetch(url);
        const statusCodeIs200Or300 = movieResult.ok;
        const movieError = movieResult.statusText;
        const movieJson = await movieResult.json();
        const movieToRender = movieJson.feed.entry;
        console.log(movieResult.ok);
        if (movieResult.status == 200) {
          // here you should return something to handle the case were all is good else the execution is going to continue and move onto to throw an exception. 
          return res.render('home', { movies: movieToRender});
         // this should do the trick and in case your rendering function return an error it would be propagated as well.
        }
        throw new Error(movieResult.status);
    });
    

    结合正确的错误处理,它会给出类似:

    app.get('/', async (req, res) => {
        const url = 'https://itunes.apple.com/us/rss/topmovies/limit=20/json';
        const movie = req.params.id
        try {
            const movieResult = await fetch(url);
            const statusCodeIs200Or300 = movieResult.ok;
            const movieError = movieResult.statusText;
            const movieJson = await movieResult.json();
            const movieToRender = movieJson.feed.entry;
            console.log(movieResult.ok);
            if (movieResult.status == 200) {
                return res.render('home', { movies: movieToRender});
            }
            throw new Error(movieResult.status);
        } catch (err) {
            // handle the error correctly here: e.g. use an error template
            res.status(500).send(error.message);
        }
    });
    

    【讨论】:

    • 它应该遵循与我编辑的相同的模式:)
    • 但是,您应该更改它的目标网址,我不知道 iTunes API,但您使用的网址返回前 20 部电影而不是具有特定 ID 的电影。
    猜你喜欢
    • 2019-04-16
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    相关资源
    最近更新 更多