bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#67862: 30.0.50; Handler-bind and ert-test-error-debug


From: Stefan Monnier
Subject: bug#67862: 30.0.50; Handler-bind and ert-test-error-debug
Date: Thu, 01 Feb 2024 21:46:32 -0500
User-agent: Gnus/5.13 (Gnus v5.13)

Hi J.P.,

>   (ert-deftest my-baseline ()
>     (error "Done wrong"))
>
>   (ert-deftest my-filter ()
>     (let ((proc
>            (start-process "my-filter" (current-buffer) "sh" "-c"
>                           "for i in $(seq 99); do echo $i; sleep 0.01; 
> done")))
>       (set-process-filter proc
>                           (lambda (_ string)
>                             (when (string-search "42" string)
>                               (error "Encountered bad value"))))
>       (with-timeout (5 (ert-fail "Timed out"))
>         (while (process-live-p proc)
>           (accept-process-output nil 0.01)))))
>
>   (ert-deftest my-timer ()
>     (run-at-time 0.2 nil (lambda () (error "Encountered a problem")))
>     (with-timeout (5 (ert-fail "Timed out"))
>       (while (accept-process-output nil 5))))

Thanks.  Indeed, `handler-bind` behaves differently than
`debug-on-error` here.  The reason is:

- For `my-filter`, process.c:6329 it's the `!NILP (Vdebug_on_error)` test in:

    internal_condition_case_1 (read_process_output_call,
                               list3 (outstream, make_lisp_proc (p), text),
                               !NILP (Vdebug_on_error) ? Qnil : Qerror,
                               read_process_output_error_handler);

- For `my-timer`, it's the `condition-case-unless-debug` in timer.el:319:

        (condition-case-unless-debug err
            ;; Timer functions should not change the current buffer.
            ;; If they do, all kinds of nasty surprises can happen,
            ;; and it can be hellish to track down their source.
            (save-current-buffer
              (apply (timer--function timer) (timer--args timer)))
          (error (message "Error running timer%s: %S"
                          (if (symbolp (timer--function timer))
                              (format-message " `%s'" (timer--function timer))
                            "")
                          err)))

The reason to catch errors in those two cases is that these codes are
normally run asynchronously, so it makes sense to catch errors rather
than propagate them up to some unrelated ambient code being executed.

For `my-filter` I can see a good argument that errors should be
propagated when you pass `proc` explicitly to `accept-process-output`
and the filter/sentinel that signals the error is indeed this very
process: in that case, there is a very clear connection between the
filter/sentinel and the ambient code which would justify propagating
the error.

For `my-timer`, on the other hand, hmm...


        Stefan






reply via email to

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