TypeScript this关键字上下文错误:AWS Lambda中existingProducts返回undefined
问题根源及解决方案
核心问题1:GraphQL装饰器导致方法无法直接调用
你在ProductService的getExistingProductsByUpcOrProductCode方法上使用了@Query和@Arg装饰器,这些是GraphQL框架(比如NestJS GraphQL)的专属装饰器,作用是将方法包装为GraphQL查询解析器。当你在AWS Lambda中直接实例化ProductService并调用该方法时:
- 装饰器会修改方法的执行逻辑,缺少GraphQL上下文支持时,原方法逻辑不会被触发(所以你看不到"I came here"的日志)
@Arg参数装饰器依赖GraphQL的参数解析机制,直接传参时无法正确映射参数,导致方法执行异常
核心问题2:SQL语法错误与潜在注入风险
你的SQL查询语句存在语法错误,并且直接拼接字符串会导致SQL注入风险:
- 缺少
WHERE关键字:原语句SELECT * from table in (...)不符合SQL语法,应该改为SELECT * from table WHERE "upc" in (...) - 字符串拼接未处理引号:如果
upcs或productCodes是字符串类型,直接拼接会导致SQL语法错误,同时存在注入风险
核心问题3:Snowflake连接池可能未正确初始化
React UI调用时,服务端环境可能已提前初始化Snowflake连接池,但AWS Lambda冷启动时,pool.snowflake可能还未完成初始化,导致execute方法调用返回undefined
修复方案
1. 分离业务逻辑与GraphQL解析器
将查询逻辑抽离为普通异步方法,让GraphQL解析器和Lambda都调用这个方法:
export class ProductService { constructor() { // 确保Snowflake连接池在构造时完成初始化 this.initSnowflakePool(); } private async initSnowflakePool() { // 这里添加Snowflake连接池的初始化逻辑,确保pool.snowflake不为undefined } // 普通业务方法,供Lambda调用 async getExistingProductsByUpcOrProductCode(upcs: string[], productCodes: string[]): Promise<Product[]> { console.log("I came here"); // 使用参数化查询避免SQL注入,同时修正语法 let query = `SELECT * from table WHERE "upc" IN (?)`; const params = [upcs]; if (productCodes.length > 0) { query += ` OR "productCode" IN (?)`; params.push(productCodes); } // 确保pool.snowflake已初始化 if (!pool.snowflake) { throw new Error("Snowflake connection pool not initialized"); } const results = await pool.snowflake.execute(query, params); return results as Product[]; } // GraphQL解析器,调用普通业务方法 @Query(() => [Product]) async getExistingProductsByUpcOrProductCodeResolver( @Arg("upcs", () => [String]) upcs: string[], @Arg("productCodes", () => [String]) productCodes: string[] ): Promise<Product[]> { return this.getExistingProductsByUpcOrProductCode(upcs, productCodes); } }
2. Lambda中调用抽离后的普通方法
修改ExcelValidator中的调用逻辑,指向普通业务方法:
async performExistingUpcValidation(products: Product[], upload: FileUpload, workbook?: Workbook): Promise<FileStatus> { // ...其他代码... const existingProducts: any[] = await this.productService.getExistingProductsByUpcOrProductCode(productUpcs, productCodes); console.log("This is the existingProduct", existingProducts); // ...其他代码... }
3. 确保Snowflake连接池初始化
在Lambda handler或ProductService构造函数中添加连接池初始化逻辑,避免冷启动时连接未就绪:
export const handler = async (upload: FileUpload, context: Context) => { // 初始化Snowflake连接池(如果全局未初始化) if (!pool.snowflake) { await initSnowflakePool(); } // ...其他代码... const parser = new ExcelValidator(new LookupService(), new ProductService()); const status = await parser.performExistingUpcValidation(products as Product[], upload, workbook); return status; };
内容的提问来源于stack exchange,提问作者Ankit0395
相关产品推荐
相关产品推荐

