无法从承诺中捕获异常,错误响应未定义



我有一些基本的Javascript代码,它调用了一个带有符号的股票API,其中符号是从一个简单的HTTP调用中提供的,如下所示:

获取 http://localhost:4000/batch_stock_prices/?stocks=12312。

我相信我误解了如何从承诺中捕获异常的语法。

抛出一个异常,12312 是我期望的无效符号,在运行节点服务器的终端上,我看到了异常,但我无法在 HTTP 响应中将其传回。响应中传回的错误为"未定义"。如何捕获异常?我需要在某个地方尝试捕获吗?

const fetch = require('node-fetch')
const { IEXCloudClient } = require("node-iex-cloud");
const { type } = require('tap');

const iex = new IEXCloudClient(fetch, {
sandbox: true,
publishable: "pk_2f78524e5........23c327e24b5",
version: "stable"
});
'use strict'
async function getCurrentPriceOfBatchStocks(_stock) {
stocks_to_submit = _stock['stocks'];
console.log(stocks_to_submit)
response = await iex
.batchSymbols(stocks_to_submit)
.price()
.catch(function (error) { // <-- doesn't seem to get called
console.log("Exception: " + error);
throw error;
})
return new Promise((resolve, reject) => {
if (response) {
resolve(response)
} else {
reject(response); // <-- response is undefined. why?
}
});
}
const batchStocksSchema = {
querystring: {
type: 'object',
properties: {
stocks: {
type: 'string'
}
},
required: ['stocks']
}
}
module.exports = async function (fastify, opts) {
fastify.get('/batch_stock_prices/', {
schema: batchStocksSchema
}, async function (request, reply) {
try {
var response = await getCurrentPriceOfBatchStocks(request.query)
// console.log(response)
return reply
.code(200)
.send(response);
} catch (e) {
console.log(e)
return reply
.code(400)
.send('Bad Request, exception: ' + e) // outputs: ...exception: undefined
}
})
}

如果不运行代码,很难确定出了什么问题,但是在代码中使用asyncawait和 promise 以及创建隐式全局变量存在几个问题。(还有各种缺失的;。如果我们对这些错误进行分类,则可能无论发生什么错误都将停止被掩盖。请参阅***评论:

"use strict"; // *** This has to be at the very beginning of the compilation
// unit, it can't be later in the code as it is in the question
const fetch = require('node-fetch')
const { IEXCloudClient } = require("node-iex-cloud");
const { type } = require('tap');
const iex = new IEXCloudClient(fetch, {
sandbox: true,
publishable: "pk_2f78524e5........23c327e24b5",
version: "stable"
});
async function getCurrentPriceOfBatchStocks(_stock) {
// *** Declare `stocks_to_submit`
const stocks_to_submit = _stock['stocks'];
// *** Declare `response`
const response = await iex.batchSymbols(stocks_to_submit).price();
// *** Don't catch the error, let it propagate; the caller should
// know whether the call succeeded or failed
// *** Don't use `new Promise`, there's no purpose to it
return response;
}
const batchStocksSchema = {
querystring: {
type: 'object',
properties: {
stocks: {
type: 'string'
}
},
required: ['stocks']
}
};
// *** This function never uses `await`, so don't make it `async`
module.exports = function (fastify, opts) {
fastify.get('/batch_stock_prices/', {
schema: batchStocksSchema
}, function (request, reply) { // *** Typically old-style callback APIs don't do
// anything with the promise an `async` function
// returns, so don't pass `async` functions into them
getCurrentPriceOfBatchStocks(request.query)
.then(response => {
// *** No `return` here, we aren't resolving the promise from `then` with the result
// of `send`
reply
.code(200)
.send(response);
})
.catch(e => {
console.log(e);
// *** No `return` here, we aren't resolving the promise from `catch` with the
// result of `send`
reply
.code(400)
.send('Bad Request, exception: ' + e);
});
});
};

为什么在这部分没有调用 catch:

response = await iex
.batchSymbols(stocks_to_submit)
.price()
.catch(function (error) { // <-- doesn't seem to get called
console.log("Exception: " + error);
throw error;
})

以及为什么响应未定义:

return new Promise((resolve, reject) => {
if (response) {
resolve(response)
} else {
reject(response); // <-- response is undefined. why?
}   });

这是原因:

通过 price(( 调用返回的承诺解析了一个未定义的值(而不是因错误而拒绝(。 您的"等待"等待这个未定义的值并将其分配给"响应"变量。

遇到问题时 price(( 已经处理了错误,然后在控制台中打印详细信息:

Error: <html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
at IEXRequest.<anonymous> (/home/runner/ArtisticAridSite/node_modules/node-iex-cloud/lib/request.js:128:35)
at step (/home/runner/ArtisticAridSite/node_modules/node-iex-cloud/lib/request.js:32:23)
at Object.next (/home/runner/ArtisticAridSite/node_modules/node-iex-cloud/lib/request.js:13:53)
at fulfilled (/home/runner/ArtisticAridSite/node_modules/node-iex-cloud/lib/request.js:4:58)

它并没有真正将链中的错误传递回您的代码。

所以关于你的问题"我怎样才能捕捉到异常? 不幸的是,您可能无法接收异常详细信息(除非您可以控制 iex 的错误处理行为(。 您可以考虑检查结果是否未定义并相应地处理。

最新更新