[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 <ttn@gnuvola.org> 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 "http://www.oecd.org/pisa/test/")
> (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)))
#+end_src
> (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))
#+end_src
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.
Footnotes:
[1]
<https://www.gnu.org/software/emacs/manual/html_node/elisp/Processing-of-Errors.html>
(info "(elisp) Processing of Errors")
[2] <https://nullprogram.com/blog/2019/03/10/>
<https://github.com/skeeto/emacs-aio>
--
Felix Dietrich