Récupérer la trace d'une erreur par programme


12

Si une erreur est signalée dans le code Emacs Lisp, et debug-on-errorc'est le cas t, j'obtiens un tampon de retour arrière qui permet de déterminer facilement où l'erreur s'est produite. Cependant, pour les erreurs qui se produisent lors du traitement d'une réponse du réseau de manière asynchrone, il serait ennuyeux de faire apparaître le tampon de trace, donc je préfère attraper l'erreur avec condition-caseet l'enregistrer.

Donc, lorsque je gère une erreur condition-case, y a-t-il un moyen d'accéder à la trace arrière au point de l'erreur? L'appel de la backtracefonction récupère la trace du code à l'intérieur du gestionnaire, ce qui n'est pas ce que je recherche.

(condition-case e
    (do-something-that-might-fail)
  (error
    (message "%s"
             ;; This gets the wrong backtrace!
             (with-temp-buffer
               (let ((standard-output (current-buffer)))
                 (backtrace)
                 (buffer-string))))))

1
Ma magithub-errorfonction fait quelque chose de similaire, je pense, mais je ne suis pas devant un ordinateur en ce moment. Cela peut aider malgré tout.
Sean Allred

1
C'est un problème général avec tout langage qui gère sa pile de manière similaire. Une façon de gérer cela est de signaler une erreur qui a déjà des informations de pile attachées. C'est-à-dire que dans votre cas, vous auriez do-something-that-might-failgénéré une trace de pile et l' auriez attachée à l'erreur qu'elle soulève.
wvxvw

1
debbugs.gnu.org/cgi/bugreport.cgi?bug=24617#8 a une suggestion (je ne l'ai pas essayée moi-même)
npostavs

Réponses:


1

La chose la plus simple à faire est de créer votre propre débogueur dans l'environnement dans lequel l'erreur se produit. Cela va quelque chose comme ceci:

(defun my-debugger (&rest debugger-args)
  (message "BACKTRACE: %s"
           (with-temp-buffer
             (let ((standard-output (current-buffer)))
               (backtrace)
               (buffer-string)))))

(let ((debugger #'my-debugger))
  (foobar)) ; Runs a function with no definition!

L' letenvironnement utilise cette fonction de débogage personnalisé my-debuggerpour la durée du code qu'il contient. Par conséquent, si vous rencontrez une erreur non gérée, le "débogueur" s'exécute, qui imprime essentiellement le message. Ce débogueur s'exécute dans l'environnement où l'erreur s'est produite, donc votre trace vous dira ce qui s'est passé.

Remarque: ce code présente deux problèmes (résolubles) que je vous laisse. Tout d'abord, vous souhaiterez probablement supprimer les premières images de la pile, car elles concernent l'invocation de backtrace. Deuxièmement, vous obtiendrez un message indiquant également l'erreur (par exemple, dans le cas ci-dessus, "let: la définition de la fonction du symbole est void: foobar"). Les problèmes ne sont pas non plus énormes, mais je ne voulais pas brouiller ma réponse.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.