【问题标题】:How to handle errors from within a callback in Nodejs如何在 Nodejs 的回调中处理错误
【发布时间】:2020-10-27 02:08:00
【问题描述】:

我有这段代码调用一个函数并有一个带有错误和数据参数的回调:

app.get('/lights', (req,res) => {
    hue.getLights(function(err, data){
        if(err) res.status(401).send("An error occured: ", err.message);
        res.send(data);
    });
})

它调用的函数是:

let getLights = function(callback){
    fetch(`http://${gateway}/api/${username}/lights`, {
        method: 'GET'
    }).then((res) => {
        if(res.ok){
            return res.json();
        }else{
            throw new Error(res.message);
        }
    }).then((json) => {
        lightsArray = []
        for (var i in json){
            lightsArray.push(`ID: ${i} Name: ${json[i]['name']}`);
        }
        return callback(lightsArray);
    });
}

当我发生错误时,未捕获错误,也未显示任何错误,应用程序崩溃并显示以下消息: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().

现在我知道我错过了很多,这是我第一次使用回调,更不用说处理错误了。

有人可以帮助我使错误回调起作用,还可以向我展示我正在做的一些缺陷,因为我知道这不会捕获所有可能发生的错误,只会捕获使用 fetch 函数引起的错误。

谢谢!

这是我的另一个功能(类似但也使用了一个 catch,我认为我也做错了):

let getLightDetails = function (ID, callback) {
    fetch(`http://${gateway}/api/${username}/lights/${ID}`, {
        method: 'GET'
    }).then((res) => {
        if(res.ok){
            return res.json();
        }else{
            throw new Error(res.message);
        }
    }).then((json) => {
        return callback(json);
    })
    .catch((err) => {
        console.log(err);
        return callback(err.message);
    });
}

【问题讨论】:

  • 将错误处理(通过.catch)添加到.thens 链的末尾。你不需要返回承诺,因为无论如何你都是通过回调来处理的。但是,在这种情况下,您应该考虑完全或始终使用节点样式 callback(err, data) 回调来转换回调样式代码。
  • 你可以使用.catch来处理错误
  • @CRice 你能看看我编辑过的帖子吗?我添加了另一个类似的功能,但我认为我使用 .catch 错误

标签: javascript node.js error-handling promise callback


【解决方案1】:

混合使用回调和承诺会使您的代码有点混乱。我会信守承诺:

app.get('/lights', (req, res) => {
  return hue.getLights()
    .then(data => {
      res.send(data);
    })
    .catch(err => {
      res.status(401).send("An error occured: ", err.message);
    });
})

hue.js

const fetch = require('node-fetch');
const gateway = "192.168.0.12";
const username = "username-A";

function fetchAPI(url, ...rest) {
    return fetch(`http://${gateway}/api/${username}${url}`, ...rest);
}

function getLights() {
    return fetchAPI(`/lights`)
    .then(res => res.json())
    .then(json => json.map((light, i) => `ID: ${i} Name: ${light.name}`));
}

function getLightDetails(id) {
    return fetchAPI(`/lights/${id}`)
    .then(res => res.json());
}

function getLightState(id) {
    return fetchAPI(`/lights/${id}`)
    .then(res => res.json())
    .then(light => `Name: ${light.name} On: ${light.state.on}`);
}

function setLightState(id, state) {
    return fetchAPI(`/lights/${id}/state`, {
        method: 'PUT',
        body: JSON.stringify({"on": state })
    }).then(res => res.json());
}

module.exports = { getLights, getLightDetails, getLightState, setLightState };

【讨论】:

  • 为您的快速回答干杯,我已经这样做了,但我仍然收到 UnhandledPromiseRejectionWarning: FetchError: request to http://192.168.0.12/api/username-A/lights/2/state failed 的错误,所以我想我没有发现 fetch API 在该代码中产生的错误?
  • @Nathan http://192.168.0.12/api/username-A/lights/2/state 从未在该函数中调用。应该是/lights。您确定将更改应用于正确的功能吗?未捕获的错误来自另一个函数
  • 该函数中的return fetch(http://${gateway}/api/${username}/lights` 行是http://192.168.0.12/api/username-A/lights/2/state 我想我目前正在检查之后的错误请求已发出并完成,在某些情况下(如我现在在),请求无法完成,并且在我第一次检查错误之前引发了新错误?
  • 我使用 Promise 重写了你的整个 hue.js 文件。查看编辑(哎呀,我忘记将一些IDs 更改为id,以及一对括号,已修复)。在您的所有路线中,不要忘记使用return hue.XXX().then(...).catch(...) 并且不要使用回调
  • 很难选择,资源很多。 MDN Docs 可能是最受信任的来源,但如果您正在寻找更短的阅读,看起来this one 很好。如果您更喜欢视觉学习者,我相信您会在 YouTube 上找到一些关于他们的好视频。 This one 真的很短而且制作精良
猜你喜欢
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 2021-02-19
  • 1970-01-01
  • 2016-12-21
  • 1970-01-01
相关资源
最近更新 更多