130 votes

Comment obtenir le numéro de ligne de la fonction d'appel JavaScript et l'URL de la source de l'appel.

J'utilise la méthode suivante pour obtenir le nom de la fonction appelante JavaScript :

var callerFunc = arguments.callee.caller.toString();
callerFuncName = (callerFunc.substring(callerFunc.indexOf("function") + 8, callerFunc.indexOf("(")) || "anoynmous")

Existe-t-il un moyen de connaître le numéro de ligne à partir duquel la méthode a été appelée ?

Par ailleurs, existe-t-il un moyen d'obtenir le nom du fichier JavaScript à partir duquel la méthode a été appelée ? Ou l'URL source ?

2 votes

Je ne pense pas que cela soit possible dans IE, sinon nous aurions un moyen de contourner ces messages d'erreur CRAPPY qui ne donnent aucun détail. Mais si c'est possible, j'aimerais bien le savoir aussi !

0 votes

Oui. Voici une fonction inter-navigateurs qui utilise les méthodes propres à chaque navigateur : github.com/eriwen/javascript-stacktrace [lien fixe]

113voto

Nathan Landis Points 391

Cela fonctionne pour moi dans chrome/QtWebView

function getErrorObject(){
    try { throw Error('') } catch(err) { return err; }
}

var err = getErrorObject();
var caller_line = err.stack.split("\n")[4];
var index = caller_line.indexOf("at ");
var clean = caller_line.slice(index+2, caller_line.length);

0 votes

Fonctionne aussi dans le nœud. Placez ceci dans votre fonction log() personnalisée (qui ajoute toute autre solution de contournement utile dont vous avez besoin - par exemple fixe pour la journalisation des tableaux Chrome) et conservez les numéros de ligne de l'endroit où vous avez appelé log().

71 votes

Il n'est pas nécessaire de lancer l'erreur ; il suffit de la créer : var caller_line = (new Error).stack.split("\n")[4]

2 votes

J'ai fusionné cette suggestion avec une autre réponse similaire pour obtenir une réponse "standardisée" de FF/Webkit -- voir stackoverflow.com/a/14841411/1037948

27voto

scotts Points 1668

Oui. Voici une fonction inter-navigateurs qui utilise les méthodes propres à chaque navigateur :

http://github.com/eriwen/javascript-stacktrace

[lien fixe]

27voto

Eli Grey Points 17553

La solution de kangax introduit une portée try..catch inutile. Si vous avez besoin d'accéder au numéro de ligne de quelque chose en JavaScript (pour autant que vous utilisiez Firefox ou Opera), accédez simplement à (new Error).lineNumber .

11 votes

Merci pour cet addon. Savez-vous s'il est possible d'obtenir le numéro de ligne de l'appel précédent ? Disons que la méthode A appelle B, et maintenant dans B je voudrais savoir dans quelle ligne sous A l'appel a été fait ?

88 votes

C'est coché, mais cela ne répond pas à la question, qui est de savoir comment obtenir le numéro de ligne de l'enregistrement. fonction d'appelant .

3 votes

De plus, c'est extrêmement limité. La meilleure solution est de lancer une erreur et d'utiliser une expression rationnelle sur le fichier error.stack qui est disponible dans tous les navigateurs modernes. Vous pouvez facilement extraire ce chemin, ce fichier, cette ligne et cette colonne. Aucun problème.

5voto

kangax Points 19954

On y parvient souvent en lançant une erreur à partir du contexte actuel, puis en analysant l'objet d'erreur à la recherche de propriétés telles que lineNumber y fileName (que certains navigateurs possèdent)

function getErrorObject(){
  try { throw Error('') } catch(err) { return err; }
}

var err = getErrorObject();

err.fileName;
err.lineNumber; // or `err.line` in WebKit

N'oubliez pas que callee.caller est dépréciée (et n'a jamais vraiment figuré dans la 3e édition de l'ECMA).

N'oubliez pas non plus que la décompilation des fonctions est spécifiée comme dépendant de l'implémentation et qu'elle peut donc donner des résultats tout à fait inattendus. J'ai écrit à ce sujet aquí y aquí .

0 votes

Merci, il semble un peu problématique d'ajouter ce code dans l'application dont j'ai besoin. (Vous connaissez une autre méthode qui n'est pas dépréciée et que je peux utiliser ?

0 votes

Vous devriez être en mesure d'inspecter l'objet d'erreur sans dépendre de la méthode dépréciée callee.caller .

0 votes

Tu n'as pas besoin de lancer l'erreur. Vous utilisez simplement (new Error).lineNumber pour accéder au numéro de ligne actuel dans un script.

4voto

rusu bogdan Points 31

Il semble que je sois un peu en retard :), mais la discussion est assez intéressante alors... voilà... En supposant que vous voulez construire un gestionnaire d'erreur, et vous utilisez votre propre classe de gestionnaire d'exception comme :

function  errorHandler(error){
    this.errorMessage = error;
}
errorHandler.prototype. displayErrors = function(){
    throw new Error(this.errorMessage);
}

Et tu enveloppes ton code comme ça :

try{
if(condition){
    //whatever...
}else{
    throw new errorHandler('Some Error Message');
}
}catch(e){
    e.displayErrors();
}

Il est fort probable que le gestionnaire d'erreurs se trouve dans un fichier .js distinct.

Vous remarquerez que dans la console d'erreur de Firefox ou de Chrome, le numéro de ligne de code (et le nom du fichier) affiché est la ligne (le fichier) qui lance l'exception 'Error' et non l'exception 'errorHandler', ce que vous voulez vraiment pour faciliter le débogage. Lancer ses propres exceptions, c'est bien, mais sur les grands projets, les localiser peut être un problème, surtout si elles ont des messages similaires. Donc, ce que vous pouvez faire est de passer une référence à un objet Error vide à votre gestionnaire d'erreur, et cette référence contiendra toutes les informations que vous voulez (par exemple, dans Firefox, vous pouvez obtenir le nom du fichier, et le numéro de ligne etc ; dans Chrome, vous obtenez quelque chose de similaire si vous lisez la propriété 'stack' de l'instance Error). Pour faire court, vous pouvez faire quelque chose comme ceci :

function  errorHandler(error, errorInstance){
    this.errorMessage = error;
    this. errorInstance = errorInstance;
}
errorHandler.prototype. displayErrors = function(){
    //add the empty error trace to your message
    this.errorMessage += '  stack trace: '+ this. errorInstance.stack;
    throw new Error(this.errorMessage);
}

try{
if(condition){
    //whatever...
}else{
    throw new errorHandler('Some Error Message', new Error());
}
}catch(e){
    e.displayErrors();
}

Vous pouvez maintenant obtenir le fichier réel et le numéro de ligne qui a déclenché votre exception personnalisée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X