2016-08-05 56 views
2

在我的控制器中,我有一個終點函數調用另一個函數,期望從被調用的函數獲得結果或捕獲錯誤。node.js - 捕獲錯誤拋出一個貓鼬回調

exports.createInvites = (req, res) => { 
    // code... 

    try { 

    generateInvitations(requirements, data => { 

     res.status(200).json({data}); 
    }); 

    } catch (err) { 
    console.log(`caught the error: ${err}`); 

    return res.status(500).json(err); 
    } 
} 

在所調用的函數generateInvites,我保存生成的對象使用貓鼬到MongoDB的,並且如果存在一個引發錯誤。

function generateInvitations(requirements, cb) { 

    const { expirationDate, credits, numOfUse, numOfInvites } = requirements; 
    let invitationCodes = []; 
    for (let i = 0; i < numOfInvites; i++) { 

    const code = randomString(CODE_LENGTH); 
    invitationCodes.push(code); 

    const invitation = new Invitation({ 
     // code, 
     numOfUse, 
     expirationDate, 
     credits 
    }); 

    invitation.save((err, obj) => { 

     if (err) { 
     throw err; // it should throw a ValidationError here 
     } 
    }); 
    } 
    cb(invitationCodes); 

} 

上面的代碼是我嘗試處理在generateInvites中拋出的錯誤。當然,我無法捕捉到任何錯誤。我做錯了什麼?我該怎麼做呢?

+1

你應該看看的承諾。異步錯誤處理對於回調來說是醜陋的。文明 – thedarklord47

回答

1

您需要處理這樣一個事實,即回調會在引發錯誤之前就會觸發很長時間,因爲它在自己的回調中。我建議Promise.all等待所有的保存操作,這將返回承諾。

function generateInvitations(requirements) { 
    const { expirationDate, credits, numOfUse, numOfInvites } = requirements; 
    let promises = []; 

    for (let i = 0; i < numOfInvites; i++) { 
    const code = randomString(CODE_LENGTH); 

    const invitation = new Invitation({ 
     // code, 
     numOfUse, 
     expirationDate, 
     credits 
    }); 

    promises.push(invitation.save()); 
    } 
    return Promise.all(promises): 
} 

然後:

generateInvitations(requirements) 
    .then(data => res.status(200).json({data})) 
    .catch(err => { 
    console.log(`caught the error: ${err}`); 
    return res.status(500).json(err); 
    }); 
+1

你的代碼包含一個重要的bug,'generateInvitations'將在所有保存操作完成之前解析,甚至會引發一個錯誤,它將不會被處理。您必須在那裏使用'Promise.all'或'Promise.map'。 – alexmac

+0

@alexmac哎呀,你是對的,謝謝。現在應該很好 – aw04

+1

mongoose函數返回promise,所以你不需要創建promise並使用'reject,resolve'回調函數。只需返回保存函數的結果:'promises.push(invitation.save())'。 – alexmac