2016-06-10 1 views
2

J'ai un itinéraire qui d'abord besoin d'interroger la base de données, puis avec les résultats, interroger un autre service Web, puis avec ce résultat rendre la page. J'ai ce flux élaboré et j'essaie de comprendre la gestion des erreurs. Étant donné que je parle à plusieurs services, j'essaie de masquer l'erreur avant de les renvoyer à exprimer.promesse expressJS et la gestion des erreurs

Voici la structure du code de la route:

Models.Episode.findById(request.params.episodeID) 
    .catch(function (error) { 
     throw (throwjs.notFound()); 
    }) 
    .then(function (episode) { 
     if (episode.getUser().id !== request.user.href) { 
      return next(throwjs.unauthorized("You do not have access to this podcast")); 
     } 
     return doSomeOtherAsyncStuff(); 
    }) 
    .then(function (queryResponse) { 
     renderPage(); 
    }) 
    .catch(function (error) { 
     next(error); 
    }); 

Mon problème est avec la première prise. Mon objectif dans cette capture est de reconditionner l'erreur et d'arrêter l'exécution et d'envoyer l'erreur pour exprimer le middleware.

Avec la façon dont il est écrit ci-dessus, l'exécution s'arrête, mais mon gestionnaire d'erreur express n'est pas appelé.

J'ai essayé de réécrire la première prise comme

.catch(function(error){ 
    return next(error); 
}) 

Mais cela ne résout pas le problème. La seule solution que j'ai trouvée est de déplacer la prise à la fin. Mais alors je perds le contexte de l'emplacement de l'échec.

Une idée de ce que je fais mal? Merci, Olivier

+0

Avez-vous réellement réécrire la première prise comme vous l'avez fait dans votre exemple? parce qu'il y a une faute de frappe. – Seth

+0

@Seth Bon point, j'ai réessayé juste pour m'assurer avec la faute de frappe et ai eu le même problème. – otusweb

+0

@ t.niese en ayant la capture au début du fil, je sais que la seule chose qui a échoué est la déclaration ci-dessus. Si j'ajoute le crochet au bas seulement, alors je ne suis pas sûr de ce qui a échoué – otusweb

Répondre

2

Je vous recommande d'adopter une approche différente afin de ne pas avoir à compter sur des chaînes de promesses à long terme. Avec l'approche suivante, vous avez découplé votre autorisation et votre validation pour séparer les middleware, car ils ne concernent pas nécessairement le gestionnaire d'épisode lui-même. De plus, cette approche est plus idiomatique à exprimer.

Un bonus supplémentaire est que vous êtes libre de transmettre des erreurs à un gestionnaire d'erreurs afin de découpler davantage vos erreurs de vos gestionnaires d'itinéraire.

function validateEpisode(req, res, next) { 
    Models.Episode 
    .findById(req.params.episodeID) 
    .then(function(episode) { 
     req.yourApp.episode = episode; 
     next() // everything's good 
    }) 
    .catch(function(error) { 
     // would be better to pass error in next 
     // so you can have a general error handler 
     // do something with the actual error 
     next(throwjs.notFound()); 
    }); 
} 

function authUserByEpisode(req, res, next) { 
    if (req.yourApp.episode.getUser().id !== req.user.href) { 
    next(throwjs.unauthorized("You do not have access to this podcast")); 
    } 

    next(); // authorized 
} 

function episodeController(req, res) { 
    // do something with req.yourApp.episode 
} 

app.get('/episode/:id', validateEpisode, authUserByEpisode, episodeController) 
+0

Intéressant. Je vais devoir expérimenter avec ça. Je suis encore relativement nouveau dans cette affaire Express. Merci! – otusweb

0

Eh bien, après tout, cela est lié au cadre de throwjs J'utilise et le fait que je suis une mauvaise utilisation

throw (throwjs.notFound()); 

devrait être

throw (new throwjs.notFound()); 

..