解决AWS部署API时的TypeError: Cannot read property '0' of undefined错误
解决AWS部署API时的"Cannot read property '0' of undefined"错误
问题概述
将API部署至AWS后触发未处理的Promise拒绝错误,核心异常为TypeError: Cannot read property '0' of undefined,日志指向resource.cache.ts第314行的refreshStudyAndConsultation方法。
错误日志
Sep 9 09:05:57 ip-172-31-32-56 web: (node:25450) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined Sep 9 09:05:57 ip-172-31-32-56 web: at ResourceCacheService.refreshStudyAndConsultation (/var/app/current/src/resource/service/resource.cache.ts:314:97) Sep 9 09:05:57 ip-172-31-32-56 web: at runMicrotasks (<anonymous>) Sep 9 09:05:57 ip-172-31-32-56 web: at processTicksAndRejections (internal/process/task_queues.js:95:5) Sep 9 09:05:57 ip-172-31-32-56 web: at ResourceCacheService.refreshCachePublicFacing (/var/app/current/src/resource/service/resource.cache.ts:98:5) Sep 9 09:05:57 ip-172-31-32-56 web: at ResourceCacheService.onModuleInit (/var/app/current/src/resource/service/resource.cache.ts:82:5) Sep 9 09:05:57 ip-172-31-32-56 web: at async Promise.all (index 0) Sep 9 09:05:57 ip-172-31-32-56 web: at Object.callModuleInitHook (/var/app/current/node_modules/@nestjs/core/hooks/on-module-init.hook.js:43:5) Sep 9 09:05:57 ip-172-31-32-56 web: at NestApplication.callInitHook (/var/app/current/node_modules/@nestjs/core/nest-application-context.js:169:13) Sep 9 09:05:57 ip-172-31-32-56 web: at NestApplication.init (/var/app/current/node_modules/@nestjs/core/nest-application.js:97:9) Sep 9 09:05:57 ip-172-31-32-56 web: at NestApplication.listen (/var/app/current/node_modules/@nestjs/core/nest-application.js:156:33) Sep 9 09:05:57 ip-172-31-32-56 web: (node:25450) 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(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=stri`ct` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 61)
相关代码
private async refreshStudyAndConsultation() { let type = ResourceType.Service; let subType = ResourceSubType.Service; let advisoryBenefit = (await this.find(type, subType.StudyAndConsultationAdvisoryBenefit))[0]; let strategicBenefit = (await this.find(type, subType.StudyAndConsultationStrategicBenefit))[0]; let cachedData = { catalog: (await this.find(type, subType.StudyAndConsultation))[0].url, mainPicture: (await this.find(type, subType.StudyAndConsultationMainPicture))[0].url, catalogMainPicture:(await this.find(type, subType.StudyAndConsultationCatalogMainPicture))[0].url, mainDesc: (await this.find(type, subType.StudyAndConsultationMainDesc))[0].content, whyUsDesc: (await this.find(type, subType.StudyAndConsultationWhyUsDesc))[0].content, methodDesc: (await this.find(type, subType.StudyAndConsultationMethodDesc))[0].content, methodItem: (await this.find(type, subType.StudyAndConsultationMethodItem)).map((e) => { return { content: e.content, title: e.title, }; }), quickLinks: await this.categoryService.findByPageName(QuickLinkPageName.StudyAndConsultation), advisoryBenefit: { content: advisoryBenefit.content, icon: advisoryBenefit.url, }, advisoryDesc: (await this.find(type, subType.StudyAndConsultationAdvisoryDesc))[0].content, advisoryItem: (await this.find(type, subType.StudyAndConsultationAdvisoryItem)).map((e) => { return { content: e.content, title: e.title, }; }), strategicBenefit: { content: strategicBenefit.content, icon: strategicBenefit.url, }, strategicDesc: (await this.find(type, subType.StudyAndConsultationStrategicDesc))[0].content, strategicItem: (await this.find(type, subType.StudyAndConsultationStrategicItem)).map((e) => { return { content: e.content, title: e.title, }; }), }; this.cacheManager.set(this.getKeyPublic(STUDY_AND_CONSULTATION), cachedData); }
分步解决指南
1. 定位具体出错的查询
错误根源是某个await this.find(...)调用返回了undefined或空数组,直接访问[0]导致异常。
- 临时在代码中添加日志,打印每个
find调用的结果,确认哪个查询无数据:// 示例:添加日志排查 const studyAndConsultation = await this.find(type, subType.StudyAndConsultation); console.log('StudyAndConsultation查询结果:', studyAndConsultation); const mainPicture = await this.find(type, subType.StudyAndConsultationMainPicture); console.log('MainPicture查询结果:', mainPicture); // 其他所有find调用同理添加日志 - 重新部署后查看AWS日志,定位返回空值的查询项。
2. 修复空值访问问题
对所有find调用的结果做空值校验,避免直接访问索引[0]:
- 方案一:使用可选链+空值合并运算符
catalog: (await this.find(type, subType.StudyAndConsultation))?.[0]?.url ?? '', mainPicture: (await this.find(type, subType.StudyAndConsultationMainPicture))?.[0]?.url ?? '', mainDesc: (await this.find(type, subType.StudyAndConsultationMainDesc))?.[0]?.content ?? '', - 方案二:提前判断并处理空结果
const studyAndConsultation = await this.find(type, subType.StudyAndConsultation); const catalogUrl = studyAndConsultation?.length ? studyAndConsultation[0].url : '';
3. 处理未捕获的Promise拒绝
给异步方法添加try/catch块,避免未处理的Promise拒绝导致进程异常:
private async refreshStudyAndConsultation() { try { // 原方法所有代码 } catch (error) { console.error('刷新学习咨询缓存失败:', error); // 可选逻辑:设置默认缓存值、触发告警或跳过本次缓存刷新 } }
4. 验证生产环境数据完整性
检查AWS关联的数据库/数据源:
- 确认所有
subType对应的资源(如StudyAndConsultation、StudyAndConsultationMainPicture等)在生产环境中是否存在 - 若某些资源为可选配置,修改代码逻辑适配空数据场景
5. 优化查询性能(可选)
当前代码多次串行调用await this.find(),可改为并行执行提升效率:
// 并行执行所有查询 const [ studyAndConsultation, mainPicture, catalogMainPicture, mainDesc, whyUsDesc, methodDesc, methodItem, advisoryBenefit, advisoryDesc, advisoryItem, strategicBenefit, strategicDesc, strategicItem ] = await Promise.all([ this.find(type, subType.StudyAndConsultation), this.find(type, subType.StudyAndConsultationMainPicture), this.find(type, subType.StudyAndConsultationCatalogMainPicture), this.find(type, subType.StudyAndConsultationMainDesc), this.find(type, subType.StudyAndConsultationWhyUsDesc), this.find(type, subType.StudyAndConsultationMethodDesc), this.find(type, subType.StudyAndConsultationMethodItem), this.find(type, subType.StudyAndConsultationAdvisoryBenefit), this.find(type, subType.StudyAndConsultationAdvisoryDesc), this.find(type, subType.StudyAndConsultationAdvisoryItem), this.find(type, subType.StudyAndConsultationStrategicBenefit), this.find(type, subType.StudyAndConsultationStrategicDesc), this.find(type, subType.StudyAndConsultationStrategicItem) ]); // 后续使用变量直接访问,例如 const cachedData = { catalog: studyAndConsultation?.[0]?.url ?? '', mainPicture: mainPicture?.[0]?.url ?? '', // 其他字段同理 }
内容的提问来源于stack exchange,提问作者user27117359
相关产品推荐
相关产品推荐

