AWS Lambda JS V3调用Secrets Manager报错:command.resolveMiddleware不是函数
使用AWS SDK v3的SecretsManagerClient时出现TypeError: command.resolveMiddleware is not a function
问题背景
使用版本^3.299.0的@aws-sdk/client-secrets-manager,搭配TypeScript 5.0.2、Node.js 18.x,tsconfig配置如下:
{ "compilerOptions": { "module": "NodeNext", "target": "ESNext", "noImplicitAny": true, "preserveConstEnums": true, "outDir": "./dist", "sourceMap": true }, "include": ["src/**/*"], "exclude": ["node_modules", "**/*.spec.ts"] }
执行密钥查询代码时触发错误:
TypeError: command.resolveMiddleware is not a function at SecretsManagerClient.send (/var/task/node_modules/@aws-sdk/smithy-client/dist-cjs/client.js:13:33) at getExistingSecret (/var/task/aws/secrets-client.js:35:10) at addSecret (/var/task/aws/secrets-client.js:8:12) at Runtime.handler (/var/task/index.js:9:29) at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1085:29)
相关代码片段:
const client = new SecretsManagerClient({ region: 'my-region' }); async function getExistingSecret(connectionDetails: ConnectionDetails): Promise<string> { console.log('checking if secret exists'); const command = getCommand(connectionDetails); console.log(`GetSecretValueCommand: ${JSON.stringify(command)}`); return client .send(command) // <----- FAILS HERE .catch(() => { console.log(`secret does not exist`); return null; }) .then((response: GetSecretValueCommandOutput) => { console.log(`secret exists arn: ${response.ARN}`); return response.ARN; }); } const getCommand = (connectionDetails: ConnectionDetails): GetSecretValueCommand => { const body = getCommandRequest(connectionDetails); console.log(`GetSecretValueRequest: ${JSON.stringify(body)}`); return { input: body } as GetSecretValueCommand; }; const getCommandRequest = (connectionDetails: ConnectionDetails): GetSecretValueCommandInput => { return { SecretId: secretName(connectionDetails) } as GetSecretValueCommandInput; };
错误原因
问题出在getCommand函数:你手动构造了一个带input属性的普通对象,并用类型断言伪装成GetSecretValueCommand,但这并不是真正的命令实例。AWS SDK v3的命令类内部包含resolveMiddleware等核心方法,这些是client.send()执行时必须调用的,手动模拟的对象没有这些方法,因此触发错误。
解决方案
必须通过new GetSecretValueCommand(input)的方式创建命令实例,而非手动构造对象。
修复后的代码
import { SecretsManagerClient, GetSecretValueCommand, GetSecretValueCommandOutput } from "@aws-sdk/client-secrets-manager"; const client = new SecretsManagerClient({ region: 'my-region' }); async function getExistingSecret(connectionDetails: ConnectionDetails): Promise<string | null> { console.log('checking if secret exists'); const commandInput = getCommandRequest(connectionDetails); console.log(`GetSecretValueRequest: ${JSON.stringify(commandInput)}`); // 正确实例化GetSecretValueCommand const command = new GetSecretValueCommand(commandInput); try { const response: GetSecretValueCommandOutput = await client.send(command); console.log(`secret exists arn: ${response.ARN}`); return response.ARN; } catch (error) { console.log(`secret does not exist`); return null; } } const getCommandRequest = (connectionDetails: ConnectionDetails): GetSecretValueCommandInput => { return { SecretId: secretName(connectionDetails) }; };
额外优化点
- 移除冗余的
getCommand函数,直接在业务逻辑中实例化命令,代码更简洁 - 用
async/await配合try/catch替代then/catch链式调用,逻辑更清晰,符合现代异步代码写法 - 修正返回值类型:原代码中
catch返回null但函数声明为Promise<string>,存在类型不匹配,修复为Promise<string | null>
内容的提问来源于stack exchange,提问作者Alex Agathocleous
相关产品推荐
相关产品推荐

