Ruby中require_relative在Lambda环境运行失效问题排查求助
问题根因
报错核心原因是sam build默认仅会打包Lambda函数CodeUri指向目录下的文件:
- 你当前SAM模板中该Lambda函数的
CodeUri大概率配置为src/Quiz_continue,构建后只有该目录下的app.rb会被放到Lambda运行环境的/var/task目录下 - 项目根目录下的
config文件夹根本没有被打包到运行环境中,require_relative "../config/environment"向上查找时只会到运行环境的/var目录,自然找不到对应文件,和报错信息里的cannot load such file -- /var/config/environment完全吻合。
单元测试能正常运行是因为本地执行单元测试时是在完整的项目目录结构下操作,能找到上层的config目录,和SAM打包后的运行环境目录结构不一致。
解决方案
方案1(最推荐):调整CodeUri路径
修改你的SAM模板(template.yaml/template.yml)中对应Lambda函数的配置:
- 将
CodeUri从原来的src/Quiz_continue改为src - 将
Handler从原来的app.lambda_handler改为Quiz_continue/app.lambda_handler
示例配置片段:
Resources: QuizContinueFunction: Type: AWS::Serverless::Function Properties: CodeUri: src/ Handler: Quiz_continue/app.lambda_handler Runtime: ruby2.7 # 其他原有配置保持不变
这个方案下sam build会把整个src目录下的所有文件打包,运行环境中的目录结构和你本地项目结构完全一致,原来的require_relative "../config/environment"代码无需修改就能正常运行。
方案2:配置打包规则包含config目录
如果你不想修改CodeUri,也可以通过BuildProperties指定需要额外打包的文件:
Resources: QuizContinueFunction: Type: AWS::Serverless::Function Properties: CodeUri: src/Quiz_continue/ Handler: app.lambda_handler Runtime: ruby2.7 BuildProperties: Includes: - "../config/**/*"
这个方案同样会把config目录打包到运行环境的对应路径,原有代码也不需要修改。
方案3:修改加载路径写法
如果需要兼容多场景的路径加载,也可以改成基于项目根目录添加加载路径的写法,代码健壮性更高:
# 把app.rb所在目录的上层目录(也就是src目录)加入Ruby加载路径 $LOAD_PATH.unshift File.expand_path('..', __dir__) require 'config/environment' def lambda_handler(event:, context:) #some lambda functionality end
这个写法不管本地测试还是SAM运行环境,只要目录结构正确都能正常加载。
内容的提问来源于stack exchange,提问作者mr_muscle
相关产品推荐
相关产品推荐

