[Top][All Lists]

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

Re: trapping process filter error in a thread

From: Felix Dietrich
Subject: Re: trapping process filter error in a thread
Date: Thu, 24 Mar 2022 03:33:50 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)

Thien-Thi Nguyen <> writes:

> I'm in the process of writing a dead-link checker and would like
> to use Emacs' threads and ‘url-http’ funcs.

You are much braver than I ;).  I am not sure if the url library is
robust enough for that task, but you can certainly try and play around
with it.

> I've run into a problem w/ GNU Emacs 27.1 (Debian), however: When
> there is a TLS problem, i am unable to trap the process filter error.
> It seems ‘condition-case’ is not the right tool for the job.
> (defvar url "";)
> (defun func ()
>   (let ((noninteractive t))
>     (condition-case nil
>         (if (url-http-file-exists-p url)
>             "ok"
>           "dead")
>       (t "error"))))
> (defvar thread (make-thread 'func))
> (message "%S" (thread-join thread))
> My questions are:
> (a) Can anyone else reproduce this on their Emacs?
>     (Obviously your Emacs has to be built w/ thread support.)

Yes (also Debianʼs 27.1), but it does not appear to have anything to do
with threads: it happens just as well when you call ‘func’ directly.

The issue seems to be that ‘url-http’ tries to ‘process-send-string’ to
a closed connection.  After being 302-redirected from an http to an
https URL, the connection is closed because of the problem with the SSL
certificate: in an interactive session Emacs would ask you whether you
would like to accept the certificated and connect despite its problems;
in batch mode the assumed answer is: “no, do not accept the certificate”
and the connection is closed.  I donʼt know if that could be fixed in
‘url-http’.  The simple ‘failed’ state for the connection also just
signals an error and would crash your script in the same way.  I have
not found a good way to handle these errors with the url library.

> (c) Is there a recommended way to trap process filter errors
>     for a noninteractive (perhaps batch) session?

Fix the process filter ;).

I found the variable ‘command-error-function’ in the Emacs Lisp manual
[1].  “This variable, if non-‘nil’, specifies a function to use to
handle errors that return control to the Emacs command loop.”  To test
it and see what it does, I set it to a dummy handler in your example
script, which appeared to have the desired result: the script exited
indicating success.

    #+begin_src emacs-lisp
      (setq command-error-function
            (lambda (data context caller)
          (message "data: %s\ncontext: %s\ncaller: %s"
               data context caller)))

> (d) Is there a more idiomatic way to work w/ threads and
>     ‘url-http’ (or async network connections, in general)?

‘url-retrieve’ is the asynchronous counterpart to
‘url-retrieve-synchronously’.  You pass it a function to call once the
retrieval is done.  It would probably suffer from the same issues with
error handling in ‘url-http’ described above.  There is also “emacs-aio”
by Chris Wellons [2] that implements the async-await pattern, but I have
not really used it besides poking at it when I tried to understand how
it works.  I have not used threads in Emacs, so I have nothing on that.

> Thank-you for any insight into this corner of Emacs Lisp!

Here is one that at one point took me a while to find: in batch mode
functions that read from the minibuffer instead read the standard input,
and an Emacs Lisp script can, therefore, read lines from a pipe like so:

    #+begin_src emacs-lisp
      (setq line-count 0)
      (while (setq line-count (1+ line-count)
                   line (ignore-errors (read-string "")))
        (message "%.03i: %s" line-count line))

Depending on the number of URLs you want to check and their length, this
might safe you a couple of Emacs invocations and initialisations when
you cannot fit all URLs on a single command line.



     (info "(elisp) Processing of Errors")

[2]  <>


Felix Dietrich

reply via email to

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