emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Attaching context info to an error


From: Stefan Monnier
Subject: Attaching context info to an error
Date: Thu, 21 Dec 2023 17:30:24 -0500
User-agent: Gnus/5.13 (Gnus v5.13)

I'm playing with `handler-bind` and trying to see how we could make use
of such a functionality in Emacs.  So far I have encountered basically
two use case:

- Triggering the debugger.  I have patches which use `handler-bind` for
  that instead of `debug-on-error` in ERT, `eval-expression` and
  `--debug-init` which circumvent the usual problems linked to (ab)using
  `debug-on-error`.

- I see a potential use in Tramp where we currently use
  `signal-hook-function` instead.  I haven't looked closely enough yet
  to be sure that it's a good replacement there, tho.

- Collecting dynamic context info.

This third use case is for thing like
`macroexp--with-extended-form-stack` where we'd like to record the
`byte-compile-form-stack` that's current when the error is signaled so
we can use that info back where we actually catch that error.

Similarly when we load a file and that signals an error, we'd like to be
able to attach to the error the information that it occurred while
loading file FOO (and that could stack up if it occurred while file FOO
was loading file BAR).

The question is: where should we put this "context" info.

One possibility is to do something like the following:


    (defun load (file ...)
      (handler-bind ((error (lambda (err)
                              (signal 'error-during-load
                                      (cons file err)))))
        ...))

so an error that occurs during `load` is turned into an
`error-during-load` (and those errors contain the original error as
well as the relevant file name, the original error could be an
`error-during-load` itself, etc...).

Similarly the byte-compiler could do

    (defun byte-compile-blabla (...)
      ...
      (condition-case err
          (handler-bind ((error
                          (lambda (err)
                            (signal 'error-during-bytecomp
                                    (cons `byte-compile-form-stack` err)))))
            ...)
        (error
         ;; `err` should now be of the form
         ;; (error-during-bytecomp STACK ERROR)
         ...)))

but I don't like the idea of changing one kind of error into another.

I thought about adding the context info to an auxiliary hash table
indexed by the "error object", but that error object tends to be
decomposed into "error-name + error-data" and then recomposed fairly
liberally, so there's no guarantee that it stays `eq` to itself.

Ideally, I'd like to "append it" to the `cdr` of an error object
(i.e. the "error data"), but I can't think of a way to do it that's
reliable and doesn't introduce nasty backward compatibility issues
(and/or require changes in many places).

Any other idea how/where we could attach that info?


        Stefan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]