Je voudrais attraper chaque erreur de fonction non définie levée. Existe-t-il une fonction globale de gestion des erreurs en JavaScript? Le cas d'utilisation capture des appels de fonction depuis le flash qui ne sont pas définis.
Je voudrais attraper chaque erreur de fonction non définie levée. Existe-t-il une fonction globale de gestion des erreurs en JavaScript? Le cas d'utilisation capture des appels de fonction depuis le flash qui ne sont pas définis.
Réponses:
Cela vous aide-t-il:
<script type="text/javascript">
window.onerror = function() {
alert("Error caught");
};
xxx();
</script>
Je ne sais pas comment il gère les erreurs Flash ...
Mise à jour: cela ne fonctionne pas dans Opera, mais je pirate Dragonfly en ce moment pour voir ce qu'il obtient. La suggestion de pirater Dragonfly est venue de cette question:
Fenêtre d'imitation. onerror dans Opera en utilisant javascript
window.onerror = function() { alert(42) };
maintenant le code dans la réponse: window.onerror = function() { alert("Error caught"); };
pas remplacé, je ne sais toujours pas ..
Attribuez l' window.onerror
événement à un gestionnaire d'événements comme:
<script type="text/javascript">
window.onerror = function(msg, url, line, col, error) {
// Note that col & error are new to the HTML 5 spec and may not be
// supported in every browser. It worked for me in Chrome.
var extra = !col ? '' : '\ncolumn: ' + col;
extra += !error ? '' : '\nerror: ' + error;
// You can view the information in an alert to see things working like this:
alert("Error: " + msg + "\nurl: " + url + "\nline: " + line + extra);
// TODO: Report this error via ajax so you can keep track
// of what pages have JS issues
var suppressErrorAlert = true;
// If you return true, then error alerts (like in older versions of
// Internet Explorer) will be suppressed.
return suppressErrorAlert;
};
</script>
Comme indiqué dans le code, si la valeur de retour de window.onerror
esttrue
le navigateur doit supprimer l'affichage d'une boîte de dialogue d'alerte.
En bref, l'événement est déclenché lorsque 1.) il y a une exception non interceptée ou 2.) une erreur de compilation se produit.
exceptions non capturées
- jeter "quelques messages"
- call_something_undefined ();
- cross_origin_iframe.contentWindow.document ;, une exception de sécurité
erreur de compilation
<script>{</script>
<script>for(;)</script>
<script>"oops</script>
setTimeout("{", 10);
, il tentera de compiler le premier argument sous forme de script
Exemple du code onerror ci-dessus en action après l'avoir ajouté à une page de test:
<script type="text/javascript">
call_something_undefined();
</script>
var error_data = {
url: document.location.href,
};
if(error != null) {
error_data['name'] = error.name; // e.g. ReferenceError
error_data['message'] = error.line;
error_data['stack'] = error.stack;
} else {
error_data['msg'] = msg;
error_data['filename'] = filename;
error_data['line'] = line;
error_data['col'] = col;
}
var xhr = new XMLHttpRequest();
xhr.open('POST', '/ajax/log_javascript_error');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status === 200) {
console.log('JS error logged');
} else if (xhr.status !== 200) {
console.error('Failed to log JS error.');
console.error(xhr);
console.error(xhr.status);
console.error(xhr.responseText);
}
};
xhr.send(JSON.stringify(error_data));
https://jsfiddle.net/nzfvm44d/
throw
est fait manuellement. stackoverflow.com/questions/15036165/…
Si votre gestion des erreurs est très sophistiquée et peut donc déclencher une erreur elle-même, il est utile d'ajouter un indicateur indiquant si vous êtes déjà en "mode de gestion des erreurs". Ainsi:
var appIsHandlingError = false;
window.onerror = function() {
if (!appIsHandlingError) {
appIsHandlingError = true;
handleError();
}
};
function handleError() {
// graceful error handling
// if successful: appIsHandlingError = false;
}
Sinon, vous pourriez vous retrouver dans une boucle infinie.
handleError
méthode.
Essayez Atatus qui fournit un suivi avancé des erreurs et une surveillance réelle des utilisateurs pour les applications Web modernes.
Permettez-moi d'expliquer comment obtenir des traces de pile qui sont raisonnablement complètes dans tous les navigateurs.
Chrome et Opera modernes prennent entièrement en charge le projet de spécification HTML 5 pour ErrorEvent et window.onerror
. Dans ces deux navigateurs, vous pouvez soit utiliser window.onerror
, soit vous lier correctement à l'événement «erreur»:
// Only Chrome & Opera pass the error object.
window.onerror = function (message, file, line, col, error) {
console.log(message, "from", error.stack);
// You can send data to your server
// sendError(data);
};
// Only Chrome & Opera have an error attribute on the event.
window.addEventListener("error", function (e) {
console.log(e.error.message, "from", e.error.stack);
// You can send data to your server
// sendError(data);
})
Malheureusement, Firefox, Safari et IE sont toujours là et nous devons également les prendre en charge. Comme le stacktrace n'est pas disponible danswindow.onerror
nous devons faire un peu plus de travail.
Il s'avère que la seule chose que nous pouvons faire pour obtenir des traces de pile à partir d'erreurs est d'envelopper tout notre code dans un try{ }catch(e){ }
bloc, puis de regarder e.stack
. Nous pouvons rendre le processus un peu plus facile avec une fonction appelée wrap qui prend une fonction et renvoie une nouvelle fonction avec une bonne gestion des erreurs.
function wrap(func) {
// Ensure we only wrap the function once.
if (!func._wrapped) {
func._wrapped = function () {
try{
func.apply(this, arguments);
} catch(e) {
console.log(e.message, "from", e.stack);
// You can send data to your server
// sendError(data);
throw e;
}
}
}
return func._wrapped;
};
Cela marche. Toute fonction que vous encapsulez manuellement aura une bonne gestion des erreurs, mais il se trouve que nous pouvons le faire automatiquement pour vous dans la plupart des cas.
En modifiant la définition globale de addEventListener
afin qu'il encapsule automatiquement le rappel, nous pouvons insérer automatiquement try{ }catch(e){ }
autour de la plupart du code. Cela permet au code existant de continuer à fonctionner, mais ajoute un suivi des exceptions de haute qualité.
var addEventListener = window.EventTarget.prototype.addEventListener;
window.EventTarget.prototype.addEventListener = function (event, callback, bubble) {
addEventListener.call(this, event, wrap(callback), bubble);
}
Nous devons également nous assurer que cela removeEventListener
continue de fonctionner. Pour le moment, ce ne sera pas le cas car l'argument de addEventListener
est modifié. Encore une fois, nous devons seulement corriger cela sur l' prototype
objet:
var removeEventListener = window.EventTarget.prototype.removeEventListener;
window.EventTarget.prototype.removeEventListener = function (event, callback, bubble) {
removeEventListener.call(this, event, callback._wrapped || callback, bubble);
}
Vous pouvez envoyer des données d'erreur à l'aide de la balise d'image comme suit
function sendError(data) {
var img = newImage(),
src = 'http://yourserver.com/jserror&data=' + encodeURIComponent(JSON.stringify(data));
img.crossOrigin = 'anonymous';
img.onload = function success() {
console.log('success', data);
};
img.onerror = img.onabort = function failure() {
console.error('failure', data);
};
img.src = src;
}
Avis de non-responsabilité: je suis développeur Web sur https://www.atatus.com/ .
http://yourserver.com
) pour recevoir et stocker. Si vous choisissez atatus.com , vous n'avez rien à faire. Incluez simplement deux lignes de script dans votre page.
Il semble que window.onerror
cela ne donne pas accès à toutes les erreurs possibles. Plus précisément, il ignore:
<img>
erreurs de chargement (réponse> = 400).<script>
erreurs de chargement (réponse> = 400).window.onerror
de manière inconnue (jquery, angular, etc.).Voici le début d'un script qui détecte bon nombre de ces erreurs, afin que vous puissiez ajouter un débogage plus robuste à votre application pendant le développement.
(function(){
/**
* Capture error data for debugging in web console.
*/
var captures = [];
/**
* Wait until `window.onload`, so any external scripts
* you might load have a chance to set their own error handlers,
* which we don't want to override.
*/
window.addEventListener('load', onload);
/**
* Custom global function to standardize
* window.onerror so it works like you'd think.
*
* @see http://www.quirksmode.org/dom/events/error.html
*/
window.onanyerror = window.onanyerror || onanyerrorx;
/**
* Hook up all error handlers after window loads.
*/
function onload() {
handleGlobal();
handleXMLHttp();
handleImage();
handleScript();
handleEvents();
}
/**
* Handle global window events.
*/
function handleGlobal() {
var onerrorx = window.onerror;
window.addEventListener('error', onerror);
function onerror(msg, url, line, col, error) {
window.onanyerror.apply(this, arguments);
if (onerrorx) return onerrorx.apply(null, arguments);
}
}
/**
* Handle ajax request errors.
*/
function handleXMLHttp() {
var sendx = XMLHttpRequest.prototype.send;
window.XMLHttpRequest.prototype.send = function(){
handleAsync(this);
return sendx.apply(this, arguments);
};
}
/**
* Handle image errors.
*/
function handleImage() {
var ImageOriginal = window.Image;
window.Image = ImageOverride;
/**
* New `Image` constructor. Might cause some problems,
* but not sure yet. This is at least a start, and works on chrome.
*/
function ImageOverride() {
var img = new ImageOriginal;
onnext(function(){ handleAsync(img); });
return img;
}
}
/**
* Handle script errors.
*/
function handleScript() {
var HTMLScriptElementOriginal = window.HTMLScriptElement;
window.HTMLScriptElement = HTMLScriptElementOverride;
/**
* New `HTMLScriptElement` constructor.
*
* Allows us to globally override onload.
* Not ideal to override stuff, but it helps with debugging.
*/
function HTMLScriptElementOverride() {
var script = new HTMLScriptElement;
onnext(function(){ handleAsync(script); });
return script;
}
}
/**
* Handle errors in events.
*
* @see http://stackoverflow.com/questions/951791/javascript-global-error-handling/31750604#31750604
*/
function handleEvents() {
var addEventListenerx = window.EventTarget.prototype.addEventListener;
window.EventTarget.prototype.addEventListener = addEventListener;
var removeEventListenerx = window.EventTarget.prototype.removeEventListener;
window.EventTarget.prototype.removeEventListener = removeEventListener;
function addEventListener(event, handler, bubble) {
var handlerx = wrap(handler);
return addEventListenerx.call(this, event, handlerx, bubble);
}
function removeEventListener(event, handler, bubble) {
handler = handler._witherror || handler;
removeEventListenerx.call(this, event, handler, bubble);
}
function wrap(fn) {
fn._witherror = witherror;
function witherror() {
try {
fn.apply(this, arguments);
} catch(e) {
window.onanyerror.apply(this, e);
throw e;
}
}
return fn;
}
}
/**
* Handle image/ajax request errors generically.
*/
function handleAsync(obj) {
var onerrorx = obj.onerror;
obj.onerror = onerror;
var onabortx = obj.onabort;
obj.onabort = onabort;
var onloadx = obj.onload;
obj.onload = onload;
/**
* Handle `onerror`.
*/
function onerror(error) {
window.onanyerror.call(this, error);
if (onerrorx) return onerrorx.apply(this, arguments);
};
/**
* Handle `onabort`.
*/
function onabort(error) {
window.onanyerror.call(this, error);
if (onabortx) return onabortx.apply(this, arguments);
};
/**
* Handle `onload`.
*
* For images, you can get a 403 response error,
* but this isn't triggered as a global on error.
* This sort of standardizes it.
*
* "there is no way to get the HTTP status from a
* request made by an img tag in JavaScript."
* @see http://stackoverflow.com/questions/8108636/how-to-get-http-status-code-of-img-tags/8108646#8108646
*/
function onload(request) {
if (request.status && request.status >= 400) {
window.onanyerror.call(this, request);
}
if (onloadx) return onloadx.apply(this, arguments);
}
}
/**
* Generic error handler.
*
* This shows the basic implementation,
* which you could override in your app.
*/
function onanyerrorx(entity) {
var display = entity;
// ajax request
if (entity instanceof XMLHttpRequest) {
// 400: http://example.com/image.png
display = entity.status + ' ' + entity.responseURL;
} else if (entity instanceof Event) {
// global window events, or image events
var target = entity.currentTarget;
display = target;
} else {
// not sure if there are others
}
capture(entity);
console.log('[onanyerror]', display, entity);
}
/**
* Capture stuff for debugging purposes.
*
* Keep them in memory so you can reference them
* in the chrome debugger as `onanyerror0` up to `onanyerror99`.
*/
function capture(entity) {
captures.push(entity);
if (captures.length > 100) captures.unshift();
// keep the last ones around
var i = captures.length;
while (--i) {
var x = captures[i];
window['onanyerror' + i] = x;
}
}
/**
* Wait til next code execution cycle as fast as possible.
*/
function onnext(fn) {
setTimeout(fn, 0);
}
})();
Il pourrait être utilisé comme ceci:
window.onanyerror = function(entity){
console.log('some error', entity);
};
Le script complet a une implémentation par défaut qui essaie d'imprimer une version "d'affichage" semi-lisible de l'entité / erreur qu'il reçoit. Peut être utilisé comme source d'inspiration pour un gestionnaire d'erreurs spécifique à l'application. L'implémentation par défaut conserve également une référence aux 100 dernières entités d'erreur, vous pouvez donc les inspecter dans la console Web après qu'elles se produisent, comme:
window.onanyerror0
window.onanyerror1
...
window.onanyerror99
Remarque: cela fonctionne en remplaçant les méthodes sur plusieurs navigateurs / constructeurs natifs. Cela peut avoir des effets secondaires imprévus. Cependant, il a été utile d'utiliser pendant le développement, pour déterminer où se produisent les erreurs, pour envoyer des journaux à des services comme NewRelic ou Sentry pendant le développement afin que nous puissions mesurer les erreurs pendant le développement, et lors de la mise en scène afin que nous puissions déboguer ce qui se passe à un niveau plus profond. Il peut ensuite être désactivé en production.
J'espère que cela t'aides.
Il faut également conserver le rappel onerror précédemment associé
<script type="text/javascript">
(function() {
var errorCallback = window.onerror;
window.onerror = function () {
// handle error condition
errorCallback && errorCallback.apply(this, arguments);
};
})();
</script>
Si vous voulez un moyen unifié de gérer à la fois les erreurs non capturées et les rejets de promesses non gérés, vous pouvez jeter un œil à la bibliothèque non capturée .
ÉDITER
<script type="text/javascript" src=".../uncaught/lib/index.js"></script>
<script type="text/javascript">
uncaught.start();
uncaught.addListener(function (error) {
console.log('Uncaught error or rejection: ', error.message);
});
</script>
Il écoute la fenêtre. rejet non géré en plus de window.onerror.
Je recommanderais d' essayer Trackjs .
C'est la journalisation des erreurs en tant que service.
C'est incroyablement simple à installer. Ajoutez simplement une ligne <script> à chaque page et c'est tout. Cela signifie également qu'il sera incroyablement simple à supprimer si vous décidez que vous ne l'aimez pas.
Il existe d'autres services comme Sentry (qui est open-source si vous pouvez héberger votre propre serveur), mais il ne fait pas ce que fait Trackjs. Trackjs enregistre l'interaction de l'utilisateur entre son navigateur et votre serveur Web afin que vous puissiez réellement suivre les étapes de l'utilisateur qui ont conduit à l'erreur, par opposition à simplement une référence de numéro de fichier et de ligne (et peut-être une trace de pile).
Vous écoutez l'événement onerror en affectant une fonction à window.onerror:
window.onerror = function (msg, url, lineNo, columnNo, error) {
var string = msg.toLowerCase();
var substring = "script error";
if (string.indexOf(substring) > -1){
alert('Script Error: See Browser Console for Detail');
} else {
alert(msg, url, lineNo, columnNo, error);
}
return false;
};