UnhandledPromiseRejectionWarning、Express.js 和 Node.js
Posted
技术标签:
【中文标题】UnhandledPromiseRejectionWarning、Express.js 和 Node.js【英文标题】:UnhandledPromiseRejectionWarning, Express.js and Node.js 【发布时间】:2018-12-31 06:27:18 【问题描述】:我对 Node.js 和 Express.js 完全陌生,并且一直在尝试通过一些示例将 Shippo API 集成到我的电子商务网络应用程序中但是我遇到了一些错误,尽管我多次检查了我的代码,但还是无法解决。
我收到 UnhandledPromiseRejectionWarning 错误,根据我在网上阅读的内容,这意味着在我的代码中某处有一个 .then() 部分没有包含“catch”或“what to-do”是请求返回错误。任何帮助将不胜感激。
这是我的代码:
var express = require('express')
var app = express()
var http = require('http');
var Raven = require('raven');
var shippo = require('shippo')('ACCESS_TOKEN');
var engines = require('consolidate');
const bodyParser = require('body-parser');
const path = require('path');
app.use(bodyParser.urlencoded(extended: true));
app.use(bodyParser.json());
app.engine('html', engines.mustache);
app.set('view engine', 'html');
//app.use(express.static(path.join(_dirname,'/')));
app.get('/', function (req, res)
res.render('Index.html');
)
app.post('/', function (req, res)
var addressFrom =
"object_purpose":"PURCHASE",
"name": "SENDER_NAME",
"company":"Shippo",
"street1":"215 Clayton St.",
"city":"San Francisco",
"state":"CA",
"zip":"94117",
"country":"US", //iso2 country code
"phone":"+1 555 341 9393",
"email":"SENDER_EMAIL",
;
// example address_to object dict
var addressTo =
"object_purpose":"PURCHASE",
"name": req.body.fnames + ' ' + req.body.lnames,
"company": req.body.company,
"street1":req.body.street,
"city":req.body.city,
"state":req.body.state,
"zip":req.body.zipcode,
"country": req.body.country, //iso2 country code
"phone":"+1 555 341 9393",
"email":"support@goshippo.com",
;
// parcel object dict
var parcelOne =
"length":"5",
"width":"5",
"height":"5",
"distance_unit":"in",
"weight":"2",
"mass_unit":"lb"
;
var shipment =
"object_purpose": "PURCHASE",
"address_from": addressFrom,
"address_to": addressTo,
"parcels": [parcelOne],
"submission_type": "DROPOFF"
;
shippo.transaction.create(
"shipment": shipment,
"servicelevel_token": "ups_standard",
"carrier_account": 'CARRIER_TOKEN',
"label_file_type": "PDF"
)
.then(function(transaction)
shippo.transaction.list(
"rate": transaction.rate
)
.then(function(mpsTransactions)
mpsTransactions.results.forEach(function(mpsTransaction)
if(mpsTransaction.object_status == "SUCCESS")
console.log("Label URL: %s", mpsTransaction.label_url);
console.log("Tracking Number: %s", mpsTransaction.tracking_number);
console.log("E-Mail: %s", mpsTransaction.object_owner);
console.log(mpsTransaction.object_status);
res.status(200).send("Label can be found under: " + mpsTransaction.label_url);
else
// hanlde error transactions
console.log("Message: %s", mpsTransactions.messages);
);
)
, function(err)
// Deal with an error
console.log("There was an error creating transaction : %s", err.detail);
res.send("something happened :O")
);
)
app.post('/successp', function (req, res)
var token = req.body.stripeToken; // Using Express
// Charge the user's card:
var charge = stripe.charges.create(
amount: 1000,
currency: "eur",
description: "Example charge",
source: token,
, function(err, charge)
// asynchronously called
);
res.send('Thanks!')
)
app.post('/successp', function (req, res)
var token = req.body.stripeToken; // Using Express
// Charge the user's card:
var charge = stripe.charges.create(
amount: 1000,
currency: "eur",
description: "Example charge",
source: token,
, function(err, charge)
// asynchronously called
);
res.send('Thanks!')
)
app.listen(3000, function ()
console.log('Example app listening on port 3000!')
)
这是我得到的错误:
侦听端口 3000 的示例应用程序! (节点:2378)UnhandledPromiseRejectionWarning (节点:2378) UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。 (拒绝编号:1) (节点:2378)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。将来,未处理的 Promise 拒绝将使用非零退出代码终止 Node.js 进程。
我也不完全确定某些行的目的(同样,我对 express 和 node.js 非常陌生)。什么是引擎和胡子?另外,我看到这个示例代码使用了 APP.POST('/succesp', function(req, res)...),那 '/succesp' 到底是什么>?我需要创建另一个 html 文件?还有,开头的“app.use(express.statc([ath.join(_dirnam,'/')));”是什么?
【问题讨论】:
【参考方案1】:使用then(FN, errorFn)
格式时需要小心一点,因为如果then
中有错误,errorFn 不会捕获它。最好使用then(fn).catch(errorFn)
。这将允许上述任何then
中的所有错误过滤到最后一个catch
进行处理。
例如,第一次调用正确捕获错误,第二次没有:
function fn()
return Promise.resolve("good")
fn()
.then(r =>
throw ("whoops")
)
.catch(err => console.log(err)) //<-- catch works here
fn()
.then(r =>
throw ("whoops")
,
err => console.log(err) // this can't catch the error above; it will only catch rejections on fn()
)
它不会显示在 sn-p 中,但如果您查看控制台,您会看到未处理的拒绝错误。
在您的代码中,您可以通过从 shippo.transaction.list
返回承诺来展平承诺链。然后你可以在最后添加一个 catch 来处理错误。
shippo.transaction.create(
"shipment": shipment,
"servicelevel_token": "ups_standard",
"carrier_account": 'CARRIER_TOKEN',
"label_file_type": "PDF"
)
.then(function(transaction)
return shippo.transaction.list( // return this promise
"rate": transaction.rate
)
.then(function(mpsTransactions) // so this can flatten out
mpsTransactions.results.forEach(function(mpsTransaction)
if(mpsTransaction.object_status == "SUCCESS")
console.log("Label URL: %s", mpsTransaction.label_url);
console.log("Tracking Number: %s", mpsTransaction.tracking_number);
console.log("E-Mail: %s", mpsTransaction.object_owner);
console.log(mpsTransaction.object_status);
res.status(200).send("Label can be found under: " + mpsTransaction.label_url);
else
// hanlde error transactions
console.log("Message: %s", mpsTransactions.messages);
);
)
.catch(function(err) // catch errors
// Deal with an error
console.log("There was an error creating transaction : %s", err.detail);
res.send("something happened :O")
);
)
由于这很难在没有所有部分的情况下在本地运行,我对错误的来源并不肯定,但看起来您正在循环中发送res.status(200).send()
,如果它得到可能会导致错误调用了两次。
【讨论】:
【参考方案2】:如果不阅读完整代码,则在使用 Promises 时不应尝试使用回调函数捕获错误。使用 .catch 块
在 Promise 中捕获错误您还应该返回第一个承诺,以便它传递给下一个 .then 函数(如果您打算将 shippo.transaction.list 作为 mpsTransactions 返回)
类似这样的:
shippo.transaction.create(
"shipment": shipment,
"servicelevel_token": "ups_standard",
"carrier_account": 'CARRIER_TOKEN',
"label_file_type": "PDF"
)
.then(function(transaction)
return shippo.transaction.list(
"rate": transaction.rate
)
)
.then(function(mpsTransactions)
mpsTransactions.results.forEach(function(mpsTransaction)
if(mpsTransaction.object_status == "SUCCESS")
console.log("Label URL: %s", mpsTransaction.label_url);
console.log("Tracking Number: %s", mpsTransaction.tracking_number);
console.log("E-Mail: %s", mpsTransaction.object_owner);
console.log(mpsTransaction.object_status);
res.status(200).send("Label can be found under: " + mpsTransaction.label_url);
else
// hanlde error transactions
console.log("Message: %s", mpsTransactions.messages);
);
)
.catch(function (error)
// Deal with an error
console.log("There was an error creating transaction : %s", err.detail);
res.send("something happened :O")
);
【讨论】:
以上是关于UnhandledPromiseRejectionWarning、Express.js 和 Node.js的主要内容,如果未能解决你的问题,请参考以下文章
[Unhandled promise rejection: TypeError: null is not an object (evaluating '_reactNativeImageCropPic