You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:57:18