Subject: Re: bug#72652: 31.0.50; url-retrieve on non-existent domain gives no indication of error

From: Greg Minshall <[email-masked]>
Date: Fri, 16 Aug 2024 22:39:11 +0300

hi, Eli,

> On MS-Windows (mytry 2) signals an error:

i see.  possibly the Emacs on windows is using a synchronous DNS
resolver (possibly not).  but, an error is better than nothing.

> On GNU/Linux, I get this in the echo-area after about 2 sec:
> 
>   Contacting host: x.example.com:443
>   url-retrieve returns  *http x.example.com:443*
>   buffer  *http x.example.com:443* contents:
>   "buffer  *http x.example.com:443* contents:
>   "
> 
> IOW, I get an empty buffer.  Why is that behavior a problem?

the problem is that there's no indication from url-retrieve that the
requested transfer has failed (or has in any way finished).  the only
reason the message about the buffer was printed out was because the
mytry script times out after 5 seconds, prints out whatever might be in
the buffer.

so, a program that calls url-retrieve for an unknown host is never
notified that anything happened.

if some sort of error is detected synchronous with the call to
url-retrieve (i.e., before url-retrieve returns to its caller),
signaling an error seems fine.

in the case where the error is detected later, then i think (if
possible) url-retrieve should cause a callback to happen, with the
`:error` data in the status parameter specifying something like "unknown
host".

in the case of (mytry 1), there is a callback (to the callback routine
specified in the invocation of url-retrieve) which passes an error
indication:
----
called back: ((:error (error http 500)
----
(one can modify mytry to print out the status given to the
callback routine -- see below.)

hth.

cheers, Greg

----
modified mytry: prints out status parameter to callback:

----
;;; ...  -*- lexical-binding: t -*-

(defun mysage (&rest args)
    "Like (message), but send ARGS to stdout, even in batch mode.
  \(In batch mode, (message) sends to stderr; the prin1, etc.,
  send to stdout."
    (princ (format "%s\n" (apply 'format args))))

(defun mytry (n)
  "Try url-retrieve on a URL.  N is 0, 1, or 2."
  (let* ((urls '("https://example.com/index.html"
                 "https://example.com/index99.html"
                 "https://x.example.com/index.html"))
         (buffer
         (url-retrieve (nth n urls)
                       (lambda (&rest results)
                         (mysage "called back: %s" results))
                       nil)))
    (mysage "url-retrieve returns %s" buffer)
    (sleep-for 5)
    (with-current-buffer buffer
      (mysage "buffer %s contents: %s" buffer (buffer-substring (point-min) (point-max))))))