javascript - 如何处理 Node.js 中基于 Promise 的业务级函数中的错误返回对象?

标签 javascript node.js express promise node-fetch

我需要创建一个名为“getLocationById”的业务级函数,它通过 REST API 从远程服务器检索一些数据。然后路由器调用该函数将数据显示在网页上。

如果 fetch 调用成功,则将 json 结果作为 Promise 返回。但是,如果 fetch 捕获错误,应该返回什么给路由器,例如远程服务器没有响应或响应时出现 500 错误?

此外,路由如何响应错误?

const fetch = require('node-fetch');    
const p_conf = require('../parse_config');  // Configuration

const db = {
    getLocationById: function(locId) {
        fetch(`${p_conf.SERVER_URL}/parse` + '/classes/location', { method: 'GET', headers: {
            'X-Parse-Application-Id': p_conf.APP_ID,
            'X-Parse-REST-API-Key': p_conf.REST_API_KEY
        }})
        .then(res1 => return res1.json())  // RETURN A PROMISE ON SUCCESS
        .catch((error) => {
            console.log(error);
            **WHAT TO RETURN TO THE ROUTER ON ERROR HERE?**
        });
    }
};

编辑:

const db_location = {
    getLocations: function() {
        //res.send("respond with 'locations' router.");
        fetch(`${p_conf.SERVER_URL}/parse` + '/classes/GCUR_LOCATION', { method: 'GET', headers: {
            'X-Parse-Application-Id': p_conf.APP_ID,
            'X-Parse-REST-API-Key': p_conf.REST_API_KEY
        }})
        .then(res1 => res1)
        .catch((error) => {
            console.log(error);
            return Promise.reject(new Error(error));
        })
    }
};

在路由器中:

router.get('/', function(req, res, next) {
  db_location.getLocations()
  .then(r => res.send(r.json()))      // WHERE AN ERROR WAS THROWN
  .catch((err) => {
    console.log(err);
    return next(err);
  })
});

抛出以下错误:

TypeError: Cannot read property 'then' of undefined

.then(r => res.send(r.json()))

进一步编辑:

然后我进行了以下更改。

业务层

getLocations: function() {
    // According to node-fetch documentation, fetch returns a Promise object.
    return fetch(`${p_conf.SERVER_URL}/parse` + '/classes/GCUR_LOCATION', { method: 'GET', headers: {
        'X-Parse-Application-Id': p_conf.APP_ID,
        'X-Parse-REST-API-Key': p_conf.REST_API_KEY
      } });

}

路由器端:

router.get('/', function(req, res, next) {
   db_location.getLocations()
  .then(r => {
    console.log("r.json(): " + r.json());
    res.send(r.json())})
  .catch((err) => {
    console.log(err);
    return next(err);
  })  
});

然后抛出一个新错误:

(node:10184) UnhandledPromiseRejectionWarning: TypeError: body used already for: http://localhost:1337/parse/classes/GCU
R_LOCATION
    at Response.consumeBody (C:\Work\tmp\node_modules\node-fetch\lib\index.js:326:30)
    at Response.json (C:\Work\tmp\node_modules\node-fetch\lib\index.js:250:22)
    at db_location.getLocations.then.r (C:\Work\tmp\ExpressApps\express-parse-server\routes\locations.js:30:13)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:228:7)
(node:10184) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing ins
ide of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejectio
n id: 5)
(node:10184) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejection
s that are not handled will terminate the Node.js process with a non-zero exit code.

我相信 fetch 函数返回了一个 Promise 对象,调用函数可以从路由接收该对象?

最佳答案

您的新编辑即将完成!首先让我们澄清一下您对fetch的误解。 。非 OK 响应不会导致 fetch Promise 被拒绝。为了确定调用是否有成功响应,请检查 response.ok .

接下来我们需要调查json方法。查看文档,我们发现它还返回一个 Promise,而不是 JSON。

这是更接近您正在寻找的路由器版本:

router.get('/', function(req, res, next) {
   db_location.getLocations()
   .then(r => {
        if (r.ok) { return r.json(); }
        throw 'Something went wrong!';
    })
   .then(data => res.json(data))
   .catch((err) => {
        console.log(err);
        next(err);
    })  
});

我认为你正在学习 Promise 真是太好了。一旦您对 promise 感到满意,请查看 async/await 。它将使您的代码更易于阅读,但了解 Promise 很重要。

关于javascript - 如何处理 Node.js 中基于 Promise 的业务级函数中的错误返回对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51391766/

相关文章:

node.js - 用于 express 请求的 before 和 after 钩子(Hook)(在任何 req 之前和任何 res 之后执行)

jquery - 2 具有相同对象的JQuery AJAX post请求

javascript - 使用 javascript 元素无缝加载页面的最佳方法是什么?

javascript - 是否可以在 Meteor 中写入 settings.json?

javascript - 函数参数被覆盖

node.js - 程序列表中的 Electron 生成器应用程序名称没有 Windows 版本

node.js - 2021 年带有 Nodejs + TypeScript 的 REST API

javascript - 播放 Dash 或 .mpd 视频 React-native(IOS)

javascript - 如何为具有线性渐变但具有透明背景的边框设置动画

javascript - 既然 Express 不带有主体解析器,我如何使用外部中间件解析 JSON?