Existe-t-il un moyen de capturer globalement toutes les exceptions, y compris les exceptions Promise. Exemple:
window.onerror = function myErrorHandler(errorMsg, url, lineNumber) {
alert("Error occured: " + errorMsg);//or any message
return false;
}
var myClass = function(){
}
var pr = new Promise(function(resolve, react){
var myInstance = new myClass();
myInstance.undefinedFunction(); // this will throw Exception
resolve(myInstance);
});
pr.then(function(result){
console.log(result);
});
// i know right will be this:
// pr.then(function(result){
// console.log(result);
// }).catch(function(e){
// console.log(e);
// });
Ce script va mourir silencieusement sans erreur. Rien dans Firebug.
Ma question est la suivante: si je fais une erreur en oubliant de l'attraper, y a-t-il un moyen de l'attraper à l'échelle mondiale?
Mise à jour, les promesses natives font maintenant ce qui suit dans la plupart des navigateurs:
window.addEventListener("unhandledrejection", function(promiseRejectionEvent) {
// handle error here, for example log
});
Nous discutions de cela l'autre jour.
Voici comment vous feriez cela avec bluebird:
window.onpossiblyunhandledexception = function(){
window.onerror.apply(this, arguments); // call
}
window.onerror = function(err){
console.log(err); // logs all errors
}
Avec Bluebird, il est également possible d'utiliser Promise.onPossiblyUnhandledRejection
. Les appels à done
ne sont pas nécessaires, car la bibliothèque détectera elle-même le rejet non pris en charge, contrairement à Q (UPDATE 2016 - j'ai maintenant écrit le code pour Q et cela se fait).
En ce qui concerne les promesses natives - , elles seront éventuellement rapportées à window.onerror ou à un nouveau gestionnaire, mais le processus de spécification n’est pas encore terminé - vous pouvez suivez-le ici .
La plupart des implémentations de promesse ne fournissent pas actuellement le type de fonctionnalité auquel vous faites référence, mais un certain nombre de bibliothèques de promesse tierces (y compris Q et bluebird ) fournit une méthode done()
qui capture et rediffuse les erreurs non interceptées, les envoyant ainsi à la console.
( Edit: Voir la réponse de Benjamin Gruenbaum sur les fonctionnalités de Bluebird pour la gestion des exceptions non capturées)
Donc, si vous avez cela, vous devez simplement suivre la règle de base selon laquelle toute promesse que vous utilisez doit être soit retournée, soit résiliée avec .done()
:
pr.then(function(result){
console.log(result);
})
.done();
Pour citer la référence Q API:
La règle d'or de
done
et dethen
est: soitreturn
votre promesse à quelqu'un d'autre, ou si la chaîne se termine avec vous, appelezdone
pour le terminer. Terminer aveccatch
n'est pas suffisant car le gestionnairecatch
peut lui-même renvoyer une erreur.
Je me rends compte que cela nécessite encore un peu de travail supplémentaire et vous pouvez toujours oublier de le faire, mais c'est une amélioration par rapport à l'obligation de .catch()
et de gérer explicitement chaque erreur, en particulier pour la raison indiquée ci-dessus.
Dans Node.js, vous pouvez utiliser:
process.on('unhandledRejection', (reason, promise) => {
console.error(`Uncaught error in`, promise);
});
Si vous écrivez du code pouvant être exécuté à la fois dans un navigateur et dans un environnement Node.js, vous pouvez envelopper votre code dans une fonction à exécution automatique comme celle-ci:
var isNode = (typeof process !== 'undefined' && typeof process.on !== 'undefined');
(function(on, unhandledRejection) {
// PUT ANY CODE HERE
on(unhandledRejection, function(error, promise) {
console.error(`Uncaught error in`, promise);
});
// PUT ANY CODE HERE
})(
isNode ? process.on.bind(process) : window.addEventListener.bind(window),
isNode ? "unhandledRejection" : "unhandledrejection"
);
Que se passerait-il si vous utilisiez ce code:
Si vous l'exécutiez dans un environnement Node.js, votre gestionnaire serait associé à l'objet de processus et exécuté lorsque vous avez une exception non interceptée dans une promesse.
Si vous l'exécutiez dans un environnement de navigateur, votre gestionnaire serait attaché à l'objet window et exécuté lorsque vous avez une exception non interceptée dans une promesse et que votre navigateur prend en charge l'événement unhandledrejection
.
Si vous l'exécutiez dans un environnement de navigateur sans la prise en charge de unhandledrejection
, vous ne pourrez pas intercepter votre exception non capturée et votre gestionnaire d'événement unhandledrejection
ne sera jamais déclenché, mais vous ne le feriez pas. obtenir des erreurs s'il n'y a aucune exception non interceptée.
Si vous utilisez Promise en natif, c'est assez simple.
Vous devez seulement .catch
ceci rejette quelque part où.
ajax(request).catch(function(rejected){
console.log(rejected);
});
Si je ne l'attrape pas quelque part, la promesse non piégée continuera à apparaître. Mais si je l'attrape quelque part ...