2017-10-29 1 views
0

Ich habe den folgenden Code:Javascript-Versprechung, warum ist unbehandelt zurückzuweisen?

function validateRole(message, cmdCalled) { 
    return new Promise(function(resolve, reject) { 
    winston.debug('Checking user\'s role'); 
    Game.findOne({ 
     running: true, 
     'players.id': message.author.id 
    }, { 
     'players.$': 1 
    }).then(function(result) { 
     console.log(result); 
     if (!result) reject('playerNotFound'); 
     if (cmdCalled === 'vote' && result.players[0].role.match(/wolf/gi)) { 
     message.author.send('Wolves are not allowed to vote!'); 
     reject('voteDenied'); 
     } 
    }, reject).catch(function(err) { 
     winston.debug(err); 
    }); 
    }); 
} 
validateRole(message,'someCommand').then(...) 

Wenn eine der bedingten Anweisungen scheitere ich error: Unhandled Rejection at: Promise Promise { <rejected> 'voteDenied' } reason: voteDenied bekommen. Warum wird das nicht durchgefangen? Oder ist dies der falsche Weg, um mit Dingen umzugehen, wäre es besser, einfach mit einem falschen Wert oder etwas aufzulösen und das Ergebnis in der then() Funktion zu behandeln?

+0

Art eines beiseite zu handhaben: Da 'Game.findOne' Rückkehr bereits ein Versprechen, was ist der Punkt eine' neue Promise' machen um es zu wickeln? Was macht dein neues Versprechen, dass das Versprechen, das aus 'Game.findOne' kommt, nicht geht? – apsillers

+0

So kann ich auflösen ('benutzerdefinierte Antwort'), wenn nötig und verwenden Sie das in .then(). – Trax

+1

Sie meinen, dass Sie 'resolve' außerhalb eines' then' verwenden möchten? Andernfalls, wenn Sie nur 'resolve' innerhalb eines' then' aufrufen möchten, können Sie stattdessen 'return' zurückgeben, da der Rückgabewert eines vorherigen' then' als Argument an ein folgendes 'then' übergeben wird. Das heißt, 'return Game.findOne (...). Then (function() {return" custom response "}). Catch (...);' würde 'benutzerdefinierte Antwort' an Ihre äußere 'validateRole (.. .). dann (...); 'Funktion. – apsillers

Antwort

2

weil Sie }, reject). das zurückgegebene Versprechen. und als reject Rückkehr undefined, gibt es keine Möglichkeit, dass .catch ausgeführt wird.

+ Verwenden Sie nicht die Promize-Konstruktor Antipattern.

Lassen Sie uns dies ein bisschen aufräumen, und Sie fügen Protokollierung, wo immer Sie wollen.

function validateRole(message, cmdCalled) { 
    return Game.findOne({ 
    running: true, 
    'players.id': message.author.id 
    }, { 
    'players.$': 1 
    }) 
    .catch(function(err){ 
    console.log("error", err); 
    //implicitely returns undefined as the `result` into the following `.then()` 
    }) 
    .then(function(result) { 
    if (!result) 
     throw 'playerNotFound'; 

    if (cmdCalled === 'vote' && result.players[0].role.match(/wolf/gi)) { 
     message.author.send('Wolves are not allowed to vote!'); 
     throw 'voteDenied'; 
    } 
    }); 
    //and after this you either have a promise with a valid result, 
    //or a rejected promise containing 'playerNotFound' or `voteDenied` 
} 

oder wenn Sie wollen Fehler mit der Bitte separat

function validateRole(message, cmdCalled) { 
    return Game.findOne({ 
    running: true, 
    'players.id': message.author.id 
    }, { 
    'players.$': 1 
    }) 
    .then(function(result) { 
    if (!result) 
     throw 'playerNotFound'; 

    if (cmdCalled === 'vote' && result.players[0].role.match(/wolf/gi)) { 
     message.author.send('Wolves are not allowed to vote!'); 
     throw 'voteDenied'; 
    } 
    }, function(err){ 
    //this will catch Errors from `findOne()` but not the errors thrown in the function above 
    console.log(err); 
    throw 'requestFailed'; 
    }); 
    //and after this you either have a promise with a valid result, 
    //or a rejected promise containing 'playerNotFound' or `voteDenied` or `requestFailed` 
} 
+0

@Trax, erweiterte die Antwort, denn auf einen zweiten Gedanken Ich weiß nicht, ob Sie beabsichtigten, Fehler in 'findOne()' als ''playerNotFound'' zu behandeln. Also habe ich eine Version hinzugefügt, in der sie separat behandelt werden – Thomas

0

In meinem Beispiel wird der interessanteste Teil des Codes nicht angezeigt und durch ... in Ihrem Beispiel ersetzt.

Von Ihrer Fehlermeldung ist zu sehen, dass validateRolePromise zurückgibt und Sie es mit der letzten Zeile des Beispielcodes zu tun haben. Wenn Ihr validateRole().then() keinen Handler für die Ablehnung von Versprechen enthält (und in Ihrem Beispiel nicht zu sehen ist), ist dieser Fehler offensichtlich - Sie behandeln keine Ablehnung von Versprechen.

Bitte überprüfen Sie entweder, ob Sie den Handler für die Ablehnung des Versprechens in den versteckten Teil Ihres Beispiels haben oder zeigen Sie, was Sie hier haben.

+0

Ich nahm an, dass catch in dem Code würde ... fangen und behandeln jede Ablehnung in den Code angezeigt. – Trax

+1

Sie fangen Fehler ** innerhalb ** Ihres Versprechens aber ** Generieren ** Zurückweisung der Versprechen von 'validateRole' zurückgegeben. Es ist natürlich nicht so offensichtlich auf den ersten Blick :) – Flying

Verwandte Themen