2017-05-21 41 views
3

我試圖理解爲什麼我遇到一個承諾拒絕異常沒有被 由我最初的try/catch在下面的代碼(完整的代碼是this branch)處理爲什麼這個Node snippet沒有捕獲被拒絕的Promise?

在此特定錯誤,nodeCf.deploy是在index.js中調用。

錯誤發生是因爲我應該在我的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; 
} 
+0

什麼是'Promise.each'? – Bergi

+0

重要的部分是使用Bluebird(.each)。它的回調不應該是異步函數。 – estus

+0

@estus啊,謝謝。然而,這不應該是一個問題:[*如果迭代器函數返回一個promise或一個thenable,那麼在繼續下一次迭代之前,promise的結果是等待的。*](http://bluebirdjs.com/docs/api /promise.each.html) – Bergi

回答

8

這是你的問題:

stackOutputs[stack.name] = await stack.deploy(envVars, stackOutputs).outputs; 

注意stack.deployasync function?這意味着它返回一個承諾 - 不是具有outputs屬性的實例。您正在訪問.outputs的承諾,即undefined,這將是await編好,但承諾和其拒絕將被忽略。

你需要寫

stackOutputs[stack.name] = (await stack.deploy(envVars, stackOutputs)).outputs; 
//      ^          ^

或使用一個輔助變量的實例。

相關問題