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

From: Eli Zaretskii <[email-masked]>
Date: Fri, 16 Aug 2024 10:43:30 +0300

> From: Greg Minshall <[email-masked]>
> Date: Fri, 16 Aug 2024 07:34:08 +0300
> 
> if url-retrieve is called with a url for a non-existent domain, it
> neither returns an error (it returns a buffer, as it is documented to
> do), nor does it seem to invoke the callback routine passed to it to
> report any error (or success, or anything else, for that matter).
> 
> the following code uses example.com.  calling
> - `(mytry 0)` should work, downloading "index.html"
> - `(mytry 1)` should give a 404 -- no such file "index99.html"
> - `(mytry 2)` doesn't give anything (but, the code ends after 5 seconds)
>   as there is no such host "x.example.com".
> 
> with 0 or 1, the callback routine is invoked, but with 2, it isn't.
> (after 5 seconds the code finishes, displays whatever might be in the
> buffer url-retrieve uses to return the results.)

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

  Debugger entered--Lisp error: (error "x.example.com/443 No such host is known. ")
    make-network-process(:name "x.example.com" :buffer #<buffer  *url-http-temp*> :host "x.example.com" :service 443 :nowait (:nowait t) :noquery nil :tls-parameters (gnutls-x509pki :priority "NORMAL:%DUMBFW" :hostname "x.example.com" :loglevel 0 :min-prime-bits nil :trustfiles nil :crlfiles nil :keylist nil :verify-flags nil :verify-error nil :pass nil :flags nil :callbacks nil) :coding nil)
    open-network-stream("x.example.com" #<buffer  *url-http-temp*> "x.example.com" 443 :nowait (:nowait t) :tls-parameters (gnutls-x509pki :priority "NORMAL:%DUMBFW" :hostname "x.example.com" :loglevel 0 :min-prime-bits nil :trustfiles nil :crlfiles nil :keylist nil :verify-flags nil :verify-error nil :pass nil :flags nil :callbacks nil) :coding nil)
    open-gnutls-stream("x.example.com" #<buffer  *url-http-temp*> "x.example.com" 443 (:type tls :nowait (:nowait t)))
    network-stream-open-tls("x.example.com" #<buffer  *url-http-temp*> "x.example.com" 443 (:type tls :nowait (:nowait t)))
    open-network-stream("x.example.com" #<buffer  *url-http-temp*> "x.example.com" 443 :type tls :nowait (:nowait t))
    url-open-stream("x.example.com" #<buffer  *url-http-temp*> "x.example.com" 443 tls)
    url-http-find-free-connection("x.example.com" 443 tls)
    url-http(#s(url :type "https" :user nil :password nil :host "x.example.com" :portspec nil :filename "/index.html" :target nil :attributes nil :fullness t :silent nil :use-cookies t :asynchronous t) #f(lambda (&rest results) [t] (mysage "called back")) (nil) nil tls)
    url-https(#s(url :type "https" :user nil :password nil :host "x.example.com" :portspec nil :filename "/index.html" :target nil :attributes nil :fullness t :silent nil :use-cookies t :asynchronous t) #f(lambda (&rest results) [t] (mysage "called back")) (nil))
    url-retrieve-internal("https://x.example.com/index.html" #f(lambda (&rest results) [t] (mysage "called back")) (nil) nil nil)
    url-retrieve("https://x.example.com/index.html" #f(lambda (&rest results) [t] (mysage "called back")) nil)
    (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")) nil))) (mysage "url-retrieve returns %s" buffer) (sleep-for 5) (save-current-buffer (set-buffer buffer) (mysage "buffer %s contents: %s" buffer (buffer-substring (point-min) (point-max)))))
    mytry(2)
    eval((mytry 2) t)
    #f(compiled-function () #<bytecode 0x127ffea33bfbce22>)()
    #f(compiled-function () #<bytecode -0x5c06e1955cf31d1>)()
    handler-bind-1(#f(compiled-function () #<bytecode -0x5c06e1955cf31d1>) (error) eval-expression--debug)
    eval-expression((mytry 2) nil nil 127)
    funcall-interactively(eval-expression (mytry 2) nil nil 127)
    call-interactively(eval-expression nil nil)
    command-execute(eval-expression)

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?