Axios捕获异常仍触发UnhandledPromiseRejection问题排查
问题分析与解决
问题描述
编写了用于处理Axios调用失败的createFunction函数,调用时触发未处理Promise拒绝错误,错误信息指向400状态码,但开发者认为已正确处理拒绝逻辑,不清楚问题根源。
代码示例
async function createFunction (url, APIKEY, vendorType) { return new Promise((resolve, reject) => { const options = { method: 'post', maxBodyLength: Infinity, url: `${url}/vendors/packages`, headers: { 'x-api-key': `${APIKEY}` }, timeout: 10000, data: { "contentType": vendorType, } }; axios.request(options) .then(response =>{ if (response.status && response.status == 200) { resolve(response); } else { reject(`createFunction Axios call failed with status ${response.status}: ${response.data}`) } }).catch(err => { reject(`createFunction Axios call failed: ${err}`); }) }); } KbartFunctions.createPackage(host,APIKEY,vendortype) .then((response) => { console.log(response); })
错误信息
[UnhandledPromiseRejection: 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(). The promise rejected with the reason "createFunction Axios call failed: AxiosError: Request failed with status code 400".] { code: 'ERR_UNHANDLED_REJECTION' }
问题原因
- 调用环节未捕获Promise拒绝:
createFunction内部确实通过reject()处理了错误,但调用KbartFunctions.createPackage时,仅用.then()处理成功场景,未添加.catch()捕获被拒绝的Promise,导致Node.js抛出未处理拒绝错误。 - 冗余的Promise包装:
createFunction本身是async函数,无需手动包裹new Promise——Axios的request方法本身返回Promise,直接用async/await语法更简洁,还能避免不必要的Promise嵌套。
解决方法
1. 给调用添加错误捕获
在createPackage的链式调用末尾追加.catch(),处理拒绝的Promise:
KbartFunctions.createPackage(host,APIKEY,vendortype) .then((response) => { console.log(response); }) .catch((err) => { console.error('调用失败:', err); });
2. 简化createFunction代码(推荐)
移除冗余的new Promise包装,用async/await重构代码:
async function createFunction(url, APIKEY, vendorType) { const options = { method: 'post', maxBodyLength: Infinity, url: `${url}/vendors/packages`, headers: { 'x-api-key': APIKEY }, timeout: 10000, data: { contentType: vendorType } }; try { const response = await axios.request(options); if (response.status !== 200) { throw new Error(`createFunction Axios call failed with status ${response.status}: ${response.data}`); } return response; } catch (err) { throw new Error(`createFunction Axios call failed: ${err}`); } }
补充说明
- Axios默认会将非2xx状态码的响应抛出为错误,若需允许其他成功状态码,可调整判断逻辑。
- 手动包裹
new Promise易引发Promise嵌套问题,async/await能让异步代码更易读、更易维护。
内容的提问来源于stack exchange,提问作者Nimrod Yanai
相关产品推荐
相关产品推荐

