Supabase边缘函数调用AWS SES报错:仍尝试读取文件系统配置
Supabase边缘函数中AWS SES SDK文件系统读取报错的解决办法
问题描述
在Supabase边缘函数里用AWS SES发邮件,已经配置了这些AWS环境变量:
AWS_ACCESS_KEY_ID=key AWS_SECRET_ACCESS_KEY=secret AWS_REGION=us-east-2 AWS_DEFAULT_REGION=us-east-2 AWS_DEFAULT_PROFILE=default AWS_SDK_LOAD_CONFIG=
虽然执行下面的代码能正常打印出凭证信息:
import { SESClient } from "npm:@aws-sdk/client-ses"; const client = new SESClient(); console.log(await client.config.credentialDefaultProvider()());
但运行时还是会因为SDK尝试读取文件系统(边缘运行时没有文件系统)抛出错误:
runtime has escaped from the event loop unexpectedly: event loop error: TypeError [ERR_INVALID_ARG_TYPE]" argument must be of type string. Received null at assertPath (ext:deno_node/path/_util.ts:10:11) at join (ext:deno_node/path/_posix.ts:77:5) at getCredentialsFilepath (file:///tmp/sb-compile-edge-runtime/node_modules/localhost/@smithy/shared-ini-file-loader/2.3.1/dist-cjs/index.js:75:117) at loadSharedConfigFiles (file:///tmp/sb-compile-edge-runtime/node_modules/localhost/@smithy/shared-ini-file-loader/2.3.1/dist-cjs/index.js:132:22) at file:///tmp/sb-compile-edge-runtime/node_modules/localhost/@smithy/node-config-provider/2.2.1/dist-cjs/index.js:51:105 at file:///tmp/sb-compile-edge-runtime/node_modules/localhost/@smithy/property-provider/2.1.1/dist-cjs/index.js:79:33 at eventLoopTick (ext:core/01_core.js:183:11) at async coalesceProvider (file:///tmp/sb-compile-edge-runtime/node_modules/localhost/@smithy/property-provider/2.1.1/dist-cjs/index.js:106:18) at async file:///tmp/sb-compile-edge-runtime/node_modules/localhost/@smithy/property-provider/2.1.1/dist-cjs/index.js:117:20
就算直接给SESClient传凭证也解决不了这个问题。
原因分析
AWS SDK v3的默认配置加载逻辑是按优先级依次尝试获取配置:先环境变量,再本地配置文件。但在Supabase边缘运行时这种无文件系统的环境里,SDK尝试构建本地配置文件路径时,因为系统路径变量是null,触发了类型错误。哪怕环境变量里的凭证已经能正常读取,这个文件系统读取的尝试还是会中断执行。
解决办法
方法1:手动指定配置,跳过文件系统加载
直接从环境变量读取凭证和区域,同时禁用SDK的配置文件加载逻辑:
import { SESClient } from "npm:@aws-sdk/client-ses"; import { fromEnv } from "npm:@aws-sdk/credential-provider-env"; const sesClient = new SESClient({ region: Deno.env.get("AWS_REGION"), credentials: fromEnv(), // 阻止SDK尝试读取本地配置文件 configFileSelector: () => Promise.reject("No config files available in edge runtime"), });
方法2:自定义配置加载链
如果需要更灵活的配置,可以只保留环境变量加载器,跳过所有文件系统相关的加载逻辑:
import { SESClient } from "npm:@aws-sdk/client-ses"; import { fromEnv } from "npm:@aws-sdk/credential-provider-env"; import { regionProvider } from "npm:@aws-sdk/node-config-provider"; const sesClient = new SESClient({ region: await regionProvider(fromEnv)(), credentials: fromEnv(), });
方法3:用环境变量强制禁用配置文件加载
把AWS_SDK_LOAD_CONFIG设为false,强制SDK只从环境变量读取配置,不再尝试加载本地文件:
AWS_SDK_LOAD_CONFIG=false
然后初始化客户端时不用额外传参数:
import { SESClient } from "npm:@aws-sdk/client-ses"; const sesClient = new SESClient({});
验证
修改后运行发送邮件的代码,确认不再出现文件系统相关的类型错误,同时邮件能正常发送。
内容的提问来源于stack exchange,提问作者Inquisitor
相关产品推荐
相关产品推荐

