如何捕获 node.js aws-sdk 函数中抛出的错误

How to catch errors thrown in node.js aws-sdk functions

我在 node.js 中使用 aws-sdk 模块,并尝试验证包含配置文件参数(作为字符串发送并用于构造 SharedIniFileCredentials 对象)和区域的配置对象。

为了验证发送的区域,我将使用已知区域和上面提供的配置文件参数创建一个 ec2 对象,然后检查是否在 ec2.describeRegions.[=14 的结果中找到该区域参数=]

我想通过捕获执行上述操作时抛出的任何异常来验证配置文件参数,并尝试使用以下设置:

var aws = require('aws-sdk'); // aws sdk
var creds = new aws.SharedIniFileCredentials({profile: profile});
var conf = new aws.Config({
    "credentials": creds,
    "region": "eu-west-1" //Known region
});
var ec2 = new aws.EC2(conf);
try {
    ec2.describeRegions({}, function (err, data) {
        if (err) throw new Error(err.message);
        //Do stuff below to check if region is found in data.Regions array
        //...
        // If not found -> errorCallback();
        successCallback();
    });
} catch(err){
    errorCallback();
}

似乎当配置文件无效时,err.message 正确显示为:

CredentialsError: Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1

但不是捕获由此构造的错误,而是未处理错误并终止进程:

C:\workspaces\njw\node_modules\aws-sdk\lib\request.js:31 throw err; ^

Error: Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1 at Response. (C:\workspaces\njw\test.js:69:24) at Request. (C:\workspaces\njw\node_modules\aws-sdk\lib\request.js:364:18)

如果我不在 describeRegions 回调中抛出错误,它将由 catch 子句正确处理。知道为什么这在回调中不起作用吗?

这里的问题是 try/catch 块的范围。

除了 successCallbackerrorCallback 未在您的示例中定义并且假设它们在我们的范围内有效并且它们的含义是函数的回调,此块

try {
  ec2.describeRegions({}, function (err, data) {
    if (err) throw new Error(err.message);
    successCallback();
  });
} catch(err){
  errorCallback();
}

相当于这个

function responseHandler(err, data) {
  if (err) throw new Error(err.message);
  successCallback();
}

try {
  ec2.describeRegions({}, responseHandler);
} catch(err){
  errorCallback();
}

并且抛出的 Error 不在 try/catch 块中。

从接受回调的异步函数返回的错误(这不是特定于 aws-sdk 的)通常被处理,将错误返回给调用者回调,例如:

function myAsyncCheck(done) {
  ec2.describeRegions({}, (err, data) => {
    if (err) return done(err);

    let result, something_bad;
    //Do checks for something bad accordingly the logic you need

    if(something_bad) return done(new Error("Something bad"));

    // Do other stuff to set result

    done(null, result);
  });
});

或者,如果您需要在全局范围内调用 ec2.describeRegions 并且 successCallbackerrorCallback 是全局范围内的函数,您可能需要按顺序更改 errorCallback接受错误作为参数,否则你无法获取错误详细信息,但这确实是一个丑陋设计模式。

var ec2 = new aws.EC2(conf);
ec2.describeRegions({}, (err, data) => {
  if (err) return errorCallback(err);

  //Do checks for something bad accordingly the logic you need

  if(something_bad) return errorCallback(new Error("Something bad"));
  successCallback();
});

希望对您有所帮助。