我想了解为什么我遇到的Promise拒绝异常没有被我的初始try / catch在下面的代码中处理(完整的代码在这个分支中 )
在这个特定的错误中,在index.js中调用了nodeCf.deploy 。
发生错误是因为我应该在我的console.log语句中使用this.deployName ,而不是stack.deployName 。
我不明白的是为什么这被认为是一种无法处理的诺言拒绝。 在初次调用nodeCf.deploy时try / catch应该不会捕获这个?
// index.js: switch (args.action) { case 'deploy': try { await nodeCf.deploy(stacks, envVars); } catch (e) { console.log(`deployment failed: `, e); process.exit(1); } break; < ... > // nodeCf module: async deploy(stacks, envVars) { var stackOutputs = {}; await Promise.each(stacks, async(stack) => { stackOutputs[stack.name] = await stack.deploy(envVars, stackOutputs).outputs; }); } // stack.deploy: async deploy(envVars, stackOutputs) { this.load(envVars, stackOutputs); await ensureBucket(this.infraBucket); const s3Resp = await this.uploadTemplate() const stackResp = await ensureAwsCfStack({ StackName: this.deployName, Parameters: this.parameters, Tags: this.tags, TemplateURL: s3Resp.Location, Capabilities: [ 'CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM' ] }); this.outputs = _.map(stackResp.Outputs, (it) => _(it).pick(['OutputKey', 'OutputValue']) .toPairs() .unzip() .tail() .fromPairs() .value()); console.log(`deployed ${stack.deployName}`); // 'stack' is causing exception return this; }I'm trying to understand why a Promise rejection exception I've encountered is not being handled by my initial try/catch in the following code (full code is in this branch)
In this particular error, nodeCf.deploy is being called in index.js.
The error is happening because I should be using this.deployName, not stack.deployName in my console.log statement.
The thing I don't understand is why this is considered an unhandle Promise rejection. Shouldn't the try/catch I have in the initial call to nodeCf.deploy catch this?
// index.js: switch (args.action) { case 'deploy': try { await nodeCf.deploy(stacks, envVars); } catch (e) { console.log(`deployment failed: `, e); process.exit(1); } break; < ... > // nodeCf module: async deploy(stacks, envVars) { var stackOutputs = {}; await Promise.each(stacks, async(stack) => { stackOutputs[stack.name] = await stack.deploy(envVars, stackOutputs).outputs; }); } // stack.deploy: async deploy(envVars, stackOutputs) { this.load(envVars, stackOutputs); await ensureBucket(this.infraBucket); const s3Resp = await this.uploadTemplate() const stackResp = await ensureAwsCfStack({ StackName: this.deployName, Parameters: this.parameters, Tags: this.tags, TemplateURL: s3Resp.Location, Capabilities: [ 'CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM' ] }); this.outputs = _.map(stackResp.Outputs, (it) => _(it).pick(['OutputKey', 'OutputValue']) .toPairs() .unzip() .tail() .fromPairs() .value()); console.log(`deployed ${stack.deployName}`); // 'stack' is causing exception return this; }最满意答案
这是你的问题:
stackOutputs[stack.name] = await stack.deploy(envVars, stackOutputs).outputs;
注意stack.deploy是一个async function ? 这意味着它返回一个承诺 - 不是带有outputs属性的实例。 您正在访问.outputs上的.outputs ,这是undefined ,这将被await很好,但承诺和它的拒绝被忽略。
你需要写信
stackOutputs[stack.name] = (await stack.deploy(envVars, stackOutputs)).outputs; // ^ ^或者为实例使用一个辅助变量。
Here's your problem:
stackOutputs[stack.name] = await stack.deploy(envVars, stackOutputs).outputs;
Notice that stack.deploy is an async function? That means it returns a promise - not the instance with the outputs property. You are accessing .outputs on the promise, which is undefined, which will be awaited just fine, but the promise and its rejection are ignored.
You'll need to write
stackOutputs[stack.name] = (await stack.deploy(envVars, stackOutputs)).outputs; // ^ ^or use a helper variable for the instance.
更多推荐
发布评论