GNU bug report logs - #78920
30.1; Process sentinel is not called when DNS lookup fails

Previous Next

Package: emacs;

Reported by: Shawn Henson <shawn <at> shenso.name>

Date: Sat, 28 Jun 2025 23:27:04 UTC

Severity: normal

Found in version 30.1

To reply to this bug, email your comments to 78920 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Sat, 28 Jun 2025 23:27:04 GMT) Full text and rfc822 format available.

Acknowledgement sent to Shawn Henson <shawn <at> shenso.name>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sat, 28 Jun 2025 23:27:05 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Shawn Henson <shawn <at> shenso.name>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.1; Process sentinel is not called when DNS lookup fails
Date: Sat, 28 Jun 2025 18:04:07 -0400
I was testing a function of mine which wraps `url-retrieve', and I found
myself confused that my callback was not being reached with bad
host names, and upon debugging discovered the process sentinel was not
being called at all. Using the Lisp debugger added further confusion
because the process status of the returned buffer would be "failed", but
this was not the case during normal evaluation due to race conditions.

You can reproduce this with make-network-process:

```
(let ((my-test-proc (make-network-process :name "dns-fail-test"
                                          :buffer "dns-fail-test-buf"
                                          :host "thisisnotarealhostname"
                                          :service 80
                                          :nowait t
                                          :sentinel (lambda (process event)
                                                      (print event)))))
  (message "process status: %s" (process-status my-test-proc)))
```

After evaluation, the *Messages* buffer includes:

```
process status: connect
```

If you run `list-processes' you will see a failed status (if you have a
decent internet connection) despite no message from the sentinel.

However, if you were to take the lisp code above, and use "gnu.org" as
the host, you will get the following output in the message buffer:

```
process status: connect
"open
"
```

Running GDB on Emacs, I could see the the status was being set to failed
at process.c:5170:

```
  /* The DNS lookup failed. */
  else if (connecting_status (p->status))
    {
      deactivate_process (proc);
      pset_status (p, (list2
               (Qfailed,
            concat3 (build_string ("Name lookup of "),
                 build_string (p->dns_request->ar_name),
                 build_string (" failed")))));
    }
```

I presume nowhere in the call stack does the sentinel get notified of
the status change. Perhaps I am wrong to assume this is unintentional,
though, as far as I'm aware the only way to detect this failure is
through a timer, which introduces unnecessary lag to handling.

I did my best to check the bug tracker and mailing lists for this issue,
but it is my first time submitting a bug so I apologize if I missed a
pre-existing report in my naivety.

Best,
Shawn


In GNU Emacs 30.1 (build 2, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.18.4, Xaw3d scroll bars) of 2025-03-30, modified by Debian
 built on sbuild
Windowing system distributor 'The X.Org Foundation', version 11.0.12101016
System Description: Debian GNU/Linux 13 (trixie)

Configured using:
 'configure --build x86_64-linux-gnu --prefix=/usr
 --sharedstatedir=/var/lib --libexecdir=/usr/libexec
 --localstatedir=/var/lib --infodir=/usr/share/info
 --mandir=/usr/share/man --with-libsystemd --with-pop=yes
 --enable-locallisppath=/etc/emacs:/usr/local/share/emacs/30.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/30.1/site-lisp:/usr/share/emacs/site-lisp
 --with-sound=alsa --without-gconf --with-mailutils --build
 x86_64-linux-gnu --prefix=/usr --sharedstatedir=/var/lib
 --libexecdir=/usr/libexec --localstatedir=/var/lib
 --infodir=/usr/share/info --mandir=/usr/share/man --with-libsystemd
 --with-pop=yes
 --enable-locallisppath=/etc/emacs:/usr/local/share/emacs/30.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/30.1/site-lisp:/usr/share/emacs/site-lisp
 --with-sound=alsa --without-gconf --with-mailutils --with-x=yes
 --with-x-toolkit=lucid --with-toolkit-scroll-bars --without-gsettings
 'CFLAGS=-g -O2 -Werror=implicit-function-declaration
 -ffile-prefix-map=/build/reproducible-path/emacs-30.1+1=. 
-fstack-protector-strong
 -fstack-clash-protection -Wformat -Werror=format-security
 -fcf-protection -Wall' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2'
 LDFLAGS=-Wl,-z,relro'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM HARFBUZZ JPEG LCMS2
LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NATIVE_COMP NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11 XAW3D XDBE XIM XINPUT2 XPM
LUCID ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: C/*l

Minor modes in effect:
  bug-reference-prog-mode: t
  projectile-mode: t
  windmove-mode: t
  server-mode: t
  display-fill-column-indicator-mode: t
  display-line-numbers-mode: t
  hl-line-mode: t
  global-evil-collection-unimpaired-mode: t
  evil-collection-unimpaired-mode: t
  evil-mode: t
  evil-local-mode: t
  nyan-mode: t
  lsp-bridge-mode: t
  yas-global-mode: t
  yas-minor-mode: t
  ivy-mode: t
  hexl-follow-ascii: t
  override-global-mode: t
  straight-use-package-mode: t
  straight-package-neutering-mode: t
  straight-live-modifications-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: t
  column-number-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  abbrev-mode: t

Load-path shadows:
/home/shenso/.config/emacs/elisp/macros hides 
/usr/share/emacs/30.1/lisp/macros
/home/shenso/.local/share/emacs/straight/build/modus-themes/theme-loaddefs 
hides /usr/share/emacs/30.1/lisp/theme-loaddefs
/home/shenso/.local/share/emacs/straight/build/bind-key/bind-key hides 
/usr/share/emacs/30.1/lisp/bind-key
/home/shenso/.local/share/emacs/straight/build/transient/transient hides 
/usr/share/emacs/30.1/lisp/transient
/home/shenso/.local/share/emacs/straight/build/jsonrpc/jsonrpc hides 
/usr/share/emacs/30.1/lisp/jsonrpc
/home/shenso/.local/share/emacs/straight/build/use-package/use-package-core 
hides /usr/share/emacs/30.1/lisp/use-package/use-package-core
/home/shenso/.local/share/emacs/straight/build/use-package/use-package-lint 
hides /usr/share/emacs/30.1/lisp/use-package/use-package-lint
/home/shenso/.local/share/emacs/straight/build/use-package/use-package-bind-key 
hides /usr/share/emacs/30.1/lisp/use-package/use-package-bind-key
/home/shenso/.local/share/emacs/straight/build/use-package/use-package-delight 
hides /usr/share/emacs/30.1/lisp/use-package/use-package-delight
/home/shenso/.local/share/emacs/straight/build/use-package/use-package-ensure-system-package 
hides 
/usr/share/emacs/30.1/lisp/use-package/use-package-ensure-system-package
/home/shenso/.local/share/emacs/straight/build/use-package/use-package-ensure 
hides /usr/share/emacs/30.1/lisp/use-package/use-package-ensure
/home/shenso/.local/share/emacs/straight/build/use-package/use-package-diminish 
hides /usr/share/emacs/30.1/lisp/use-package/use-package-diminish
/home/shenso/.local/share/emacs/straight/build/use-package/use-package 
hides /usr/share/emacs/30.1/lisp/use-package/use-package
/home/shenso/.local/share/emacs/straight/build/use-package/use-package-jump 
hides /usr/share/emacs/30.1/lisp/use-package/use-package-jump
/home/shenso/.local/share/emacs/straight/build/compat/compat hides 
/usr/share/emacs/30.1/lisp/emacs-lisp/compat
/home/shenso/.local/share/emacs/straight/build/map/map hides 
/usr/share/emacs/30.1/lisp/emacs-lisp/map
/home/shenso/.local/share/emacs/straight/build/seq/seq hides 
/usr/share/emacs/30.1/lisp/emacs-lisp/seq

Features:
(shadow emacsbug message rfc822 mml mml-sec epa epg rfc6068 epg-config
gnus-util mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev
gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums mm-util
mail-prsvr mail-utils goto-addr view add-log which-func octave vc-hg
vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs log-view pcvs-util js
c-ts-common imenu loaddefs-gen face-remap yank-media mail-extr cua-base
modus-operandi-tritanopia-theme modus-themes find-lisp vc bug-reference
cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine
cc-vars cc-defs sort find-dired all-the-icons-dired mule-util delsel
tabify jka-compr tramp-cache time-stamp tramp-sh shortdoc ivy-overlay
ielm asyncio-test-promise ert ewoc misearch multi-isearch help-fns
radix-tree cl-print asyncio evil-collection-edebug edebug
evil-collection-debug debug backtrace vc-git evil-collection-diff-mode
diff-mode track-changes vc-dispatcher go-mode url url-proxy url-privacy
url-expand url-methods url-history url-cookie generate-lisp-file
url-domsuf url-util mailcap find-file ffap etags fileloop projectile
ibuf-ext ibuffer ibuffer-loaddefs windmove network-stream puny nsm time
server checkdoc lisp-mnt flymake display-fill-column-indicator
display-line-numbers hl-line cus-start evil-org-agenda evil-org
org-element org-persist org-id org-refile org-element-ast inline
avl-tree generator evil-dired evil-collection-ivy
evil-collection-unimpaired evil-collection-info evil-collection-help
evil-collection-grep evil-collection-dired evil-collection-custom
evil-collection-calendar evil-collection annalist evil evil-integration
evil-maps evil-commands reveal evil-jumps evil-command-window evil-types
evil-search evil-ex evil-macros evil-repeat evil-states evil-core
evil-common rect evil-vars diminish diminish-autoloads nyan-mode
nyan-mode-autoloads all-the-icons-dired-autoloads all-the-icons
all-the-icons-faces data-material data-weathericons data-octicons
data-fileicons data-faicons data-alltheicons all-the-icons-autoloads
org-pretty-theme org-indent org ob ob-tangle ob-ref ob-lob ob-table
ob-exp org-macro org-src sh-script smie executable ob-comint
org-pcomplete org-list org-footnote org-faces org-entities ob-emacs-lisp
ob-core ob-eval org-cycle org-table ol org-fold org-fold-core org-keys
oc org-loaddefs find-func cal-menu calendar cal-loaddefs org-compat
org-version org-macs shenso-font-theme theme-timer
modus-themes-autoloads nordic-night-theme nordic-night-theme-autoloads
yaml-mode-autoloads lsp-bridge lsp-bridge-rust
lsp-bridge-semantic-tokens lsp-bridge-dart lsp-bridge-inlay-hint
lsp-bridge-org-babel lsp-bridge-lsp-installer lsp-bridge-diagnostic
lsp-bridge-code-action acm acm-quick-access acm-backend-capf
acm-backend-tabby acm-backend-jupyter acm-backend-org-roam
acm-backend-copilot acm-backend-codeium array acm-backend-ctags xref
acm-backend-citre acm-backend-tabnine acm-backend-telega
acm-backend-tempel acm-backend-search-sdcv-words
acm-backend-search-file-words acm-backend-path
acm-backend-lsp-workspace-symbol acm-backend-lsp acm-backend-elisp
acm-backend-yas acm-icon svg dom xml lsp-bridge-call-hierarchy
lsp-bridge-peek comp comp-cstr comp-run comp-common lsp-bridge-jdtls
lsp-bridge-ref derived grep lsp-bridge-epc acm-frame diff markdown-mode
url-parse url-vars thingatpt noutline outline csv-mode-autoloads
sql-indent-autoloads bigquery bigquery-autoloads
typescript-mode-autoloads go-mode-autoloads flutter-autoloads
dart-mode-autoloads yasnippet yasnippet-autoloads shenso-windowing
advice projectile-autoloads ivy ivy-faces colir ivy-autoloads
dired-subtree-hack dired-subtree dired-hacks-utils dired-aux dash
dired-subtree-autoloads dired-hacks-utils-autoloads dash-autoloads
gptel-autoloads ement-autoloads svg-lib-autoloads
taxy-magit-section-autoloads taxy-autoloads plz-autoloads
persist-autoloads map-autoloads dape jsonrpc pcase warnings tramp rx
trampver tramp-integration files-x tramp-message tramp-compat xdg shell
pcomplete parse-time iso8601 time-date format-spec auth-source eieio
eieio-core password-cache tramp-loaddefs hexl gdb-mi bindat gud project
compile text-property-search repeat comint ansi-osc ansi-color ring
pulse color dape-autoloads jsonrpc-autoloads lsp-bridge-autoloads
markdown-mode-autoloads magit-autoloads with-editor-autoloads
transient-autoloads magit-section-autoloads llama-autoloads
compat-autoloads seq-autoloads exec-path-from-shell json map
exec-path-from-shell-autoloads vterm-autoloads free-keys
free-keys-autoloads evil-org-autoloads evil-collection-autoloads
annalist-autoloads edmacro kmacro byte-opt evil-autoloads
goto-chg-autoloads finder-inf use-package-bind-key bind-key easy-mmode
treesit use-package-ensure use-package-core use-package-autoloads info
bind-key-autoloads straight-autoloads cl-extra help-mode straight subr-x
cl-macs gv bytecomp byte-compile package-helper dired dired-loaddefs
macros cl-seq cus-edit pp cus-load icons wid-edit cl-loaddefs cl-lib rmc
iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook
vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd touch-screen tool-bar dnd fontset image regexp-opt
fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode
register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting font-render-setting cairo
x-toolkit xinput2 x multi-tty move-toolbar make-network-process
native-compile emacs)

Memory information:
((conses 16 1101798 3861611) (symbols 48 48350 2)
 (strings 32 176930 140541) (string-bytes 1 6746814)
 (vectors 16 80423) (vector-slots 8 1325257 675661)
 (floats 8 2282 61226) (intervals 56 51724 47167) (buffers 992 61))





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Sun, 29 Jun 2025 05:14:03 GMT) Full text and rfc822 format available.

Message #8 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Shawn Henson <shawn <at> shenso.name>
Cc: 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1;
 Process sentinel is not called when DNS lookup fails
Date: Sun, 29 Jun 2025 08:13:04 +0300
> Date: Sat, 28 Jun 2025 18:04:07 -0400
> From: Shawn Henson <shawn <at> shenso.name>
> 
> I was testing a function of mine which wraps `url-retrieve', and I found
> myself confused that my callback was not being reached with bad
> host names, and upon debugging discovered the process sentinel was not
> being called at all. Using the Lisp debugger added further confusion
> because the process status of the returned buffer would be "failed", but
> this was not the case during normal evaluation due to race conditions.
> 
> You can reproduce this with make-network-process:
> 
> ```
> (let ((my-test-proc (make-network-process :name "dns-fail-test"
>                                            :buffer "dns-fail-test-buf"
>                                            :host "thisisnotarealhostname"
>                                            :service 80
>                                            :nowait t
>                                            :sentinel (lambda (process event)
>                                                        (print event)))))
>    (message "process status: %s" (process-status my-test-proc)))
> ```
> 
> After evaluation, the *Messages* buffer includes:
> 
> ```
> process status: connect
> ```

What happens if you use ':nowait nil' instead?  Is the sentinel get
called?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Sun, 29 Jun 2025 08:00:04 GMT) Full text and rfc822 format available.

Message #11 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Shawn Henson <shawn <at> shenso.name>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Sun, 29 Jun 2025 03:59:17 -0400
On 6/29/25 1:13 AM, Eli Zaretskii wrote:
>> Date: Sat, 28 Jun 2025 18:04:07 -0400
>> From: Shawn Henson <shawn <at> shenso.name>
>>
>> I was testing a function of mine which wraps `url-retrieve', and I found
>> myself confused that my callback was not being reached with bad
>> host names, and upon debugging discovered the process sentinel was not
>> being called at all. Using the Lisp debugger added further confusion
>> because the process status of the returned buffer would be "failed", but
>> this was not the case during normal evaluation due to race conditions.
>>
>> You can reproduce this with make-network-process:
>>
>> ```
>> (let ((my-test-proc (make-network-process :name "dns-fail-test"
>>                                             :buffer "dns-fail-test-buf"
>>                                             :host "thisisnotarealhostname"
>>                                             :service 80
>>                                             :nowait t
>>                                             :sentinel (lambda (process event)
>>                                                         (print event)))))
>>     (message "process status: %s" (process-status my-test-proc)))
>> ```
>>
>> After evaluation, the *Messages* buffer includes:
>>
>> ```
>> process status: connect
>> ```
> What happens if you use ':nowait nil' instead?  Is the sentinel get
> called?

In this case, an error is signaled upon evaluating the function:

```
Debugger entered--Lisp error: (error "thisisnotarealhostname/80 Name or 
service not known")
  make-network-process(:name "dns-fail-test" :buffer 
"dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait 
nil :sentinel #f(lambda (process event) [t] (print event)))
```

This seems in line with the function documentation, which seems to 
confirm the sentinel should be
called when it is 't', which is the case for `url-retrieve'.

```
:nowait BOOL -- If NOWAIT is non-nil for a stream type client
process, return without waiting for the connection to complete;
instead, the sentinel function will be called with second arg matching
"open" (if successful) or "failed" when the connect completes.
Default is to use a blocking connect (i.e. wait) for stream type
connections.
```





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Sun, 29 Jun 2025 08:19:03 GMT) Full text and rfc822 format available.

Message #14 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Shawn Henson <shawn <at> shenso.name>, Robert Pluim <rpluim <at> gmail.com>
Cc: 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Sun, 29 Jun 2025 11:18:10 +0300
> Date: Sun, 29 Jun 2025 03:59:17 -0400
> Cc: 78920 <at> debbugs.gnu.org
> From: Shawn Henson <shawn <at> shenso.name>
> 
> 
> On 6/29/25 1:13 AM, Eli Zaretskii wrote:
> >> Date: Sat, 28 Jun 2025 18:04:07 -0400
> >> From: Shawn Henson <shawn <at> shenso.name>
> >>
> >> I was testing a function of mine which wraps `url-retrieve', and I found
> >> myself confused that my callback was not being reached with bad
> >> host names, and upon debugging discovered the process sentinel was not
> >> being called at all. Using the Lisp debugger added further confusion
> >> because the process status of the returned buffer would be "failed", but
> >> this was not the case during normal evaluation due to race conditions.
> >>
> >> You can reproduce this with make-network-process:
> >>
> >> ```
> >> (let ((my-test-proc (make-network-process :name "dns-fail-test"
> >>                                             :buffer "dns-fail-test-buf"
> >>                                             :host "thisisnotarealhostname"
> >>                                             :service 80
> >>                                             :nowait t
> >>                                             :sentinel (lambda (process event)
> >>                                                         (print event)))))
> >>     (message "process status: %s" (process-status my-test-proc)))
> >> ```
> >>
> >> After evaluation, the *Messages* buffer includes:
> >>
> >> ```
> >> process status: connect
> >> ```
> > What happens if you use ':nowait nil' instead?  Is the sentinel get
> > called?
> 
> In this case, an error is signaled upon evaluating the function:
> 
> ```
> Debugger entered--Lisp error: (error "thisisnotarealhostname/80 Name or 
> service not known")
>    make-network-process(:name "dns-fail-test" :buffer 
> "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait 
> nil :sentinel #f(lambda (process event) [t] (print event)))
> ```
> 
> This seems in line with the function documentation, which seems to 
> confirm the sentinel should be
> called when it is 't', which is the case for `url-retrieve'.
> 
> ```
> :nowait BOOL -- If NOWAIT is non-nil for a stream type client
> process, return without waiting for the connection to complete;
> instead, the sentinel function will be called with second arg matching
> "open" (if successful) or "failed" when the connect completes.
> Default is to use a blocking connect (i.e. wait) for stream type
> connections.
> ```

Yes, but when the problem is with the DNS resolution, there's no
connection, and technically no running process.  The "failed" status
is never reached because of that.

Robert, WDYT?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Sun, 29 Jun 2025 09:18:02 GMT) Full text and rfc822 format available.

Message #17 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Shawn Henson <shawn <at> shenso.name>
To: Eli Zaretskii <eliz <at> gnu.org>, Robert Pluim <rpluim <at> gmail.com>
Cc: 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Sun, 29 Jun 2025 05:17:18 -0400
On 6/29/25 4:18 AM, Eli Zaretskii wrote:
>> Date: Sun, 29 Jun 2025 03:59:17 -0400
>> Cc: 78920 <at> debbugs.gnu.org
>> From: Shawn Henson <shawn <at> shenso.name>
>>
>>
>> On 6/29/25 1:13 AM, Eli Zaretskii wrote:
>>>> Date: Sat, 28 Jun 2025 18:04:07 -0400
>>>> From: Shawn Henson <shawn <at> shenso.name>
>>>>
>>>> I was testing a function of mine which wraps `url-retrieve', and I found
>>>> myself confused that my callback was not being reached with bad
>>>> host names, and upon debugging discovered the process sentinel was not
>>>> being called at all. Using the Lisp debugger added further confusion
>>>> because the process status of the returned buffer would be "failed", but
>>>> this was not the case during normal evaluation due to race conditions.
>>>>
>>>> You can reproduce this with make-network-process:
>>>>
>>>> ```
>>>> (let ((my-test-proc (make-network-process :name "dns-fail-test"
>>>>                                              :buffer "dns-fail-test-buf"
>>>>                                              :host "thisisnotarealhostname"
>>>>                                              :service 80
>>>>                                              :nowait t
>>>>                                              :sentinel (lambda (process event)
>>>>                                                          (print event)))))
>>>>      (message "process status: %s" (process-status my-test-proc)))
>>>> ```
>>>>
>>>> After evaluation, the *Messages* buffer includes:
>>>>
>>>> ```
>>>> process status: connect
>>>> ```
>>> What happens if you use ':nowait nil' instead?  Is the sentinel get
>>> called?
>> In this case, an error is signaled upon evaluating the function:
>>
>> ```
>> Debugger entered--Lisp error: (error "thisisnotarealhostname/80 Name or
>> service not known")
>>     make-network-process(:name "dns-fail-test" :buffer
>> "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait
>> nil :sentinel #f(lambda (process event) [t] (print event)))
>> ```
>>
>> This seems in line with the function documentation, which seems to
>> confirm the sentinel should be
>> called when it is 't', which is the case for `url-retrieve'.
>>
>> ```
>> :nowait BOOL -- If NOWAIT is non-nil for a stream type client
>> process, return without waiting for the connection to complete;
>> instead, the sentinel function will be called with second arg matching
>> "open" (if successful) or "failed" when the connect completes.
>> Default is to use a blocking connect (i.e. wait) for stream type
>> connections.
>> ```
> Yes, but when the problem is with the DNS resolution, there's no 
> connection, and technically no running process. The "failed" status is 
> never reached because of that. Robert, WDYT? 
I see, though, interestingly if you are to run the `list-processes' you 
will see it persist there
indefinitely with a "failed" status.  And if you do kill it, then the 
process sentinel will be
called.

```
Process   PID      Status  Buffer         TTY Thread         Command
dns-fail-test   --      failed  dns-fail-test-buf --           
Main         (network connection to nil:nil)
```





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Sun, 29 Jun 2025 16:29:02 GMT) Full text and rfc822 format available.

Message #20 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Robert Pluim <rpluim <at> gmail.com>
To: Shawn Henson <shawn <at> shenso.name>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Sun, 29 Jun 2025 18:28:14 +0200
>>>>> On Sun, 29 Jun 2025 05:17:18 -0400, Shawn Henson <shawn <at> shenso.name> said:
    >> Yes, but when the problem is with the DNS resolution, there's no
    >> connection, and technically no running process. The "failed" status
    >> is never reached because of that. Robert, WDYT? 

For ":nowait nil", yes. Except in that case we should probably not leave
a "failed" process lying around.

    Shawn> I see, though, interestingly if you are to run the `list-processes'
    Shawn> you will see it persist there
    Shawn> indefinitely with a "failed" status.  And if you do kill it, then the
    Shawn> process sentinel will be
    Shawn> called.

Hmm, that seems wrong. When using async DNS, which we will only do for
":nowait t", Emacs will create the process, and then deactivate it
upon DNS failure with a status of "failed". I donʼt think the sentinel
gets called, but I havenʼt tested it.

I wonder what Emacs does for ":nowait t" without async DNS, when the
connect fails. Iʼd expect it to call the sentinel with a "failed"
status.

Robert
-- 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Sun, 29 Jun 2025 21:23:01 GMT) Full text and rfc822 format available.

Message #23 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Shawn Henson <shawn <at> shenso.name>
To: Robert Pluim <rpluim <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Sun, 29 Jun 2025 17:22:36 -0400
Robert Pluim <rpluim <at> gmail.com> writes:

>>>>>> On Sun, 29 Jun 2025 05:17:18 -0400, Shawn Henson <shawn <at> shenso.name> said:
>     Shawn> I see, though, interestingly if you are to run the `list-processes'
>     Shawn> you will see it persist there
>     Shawn> indefinitely with a "failed" status.  And if you do kill it, then the
>     Shawn> process sentinel will be
>     Shawn> called.
>
> Hmm, that seems wrong. When using async DNS, which we will only do for
> ":nowait t", Emacs will create the process, and then deactivate it
> upon DNS failure with a status of "failed". I donʼt think the sentinel
> gets called, but I havenʼt tested it.

Sorry, I miswrote, I said "killing", but I meant to say the sentinel only gets
called when *deleting* the process (manually, with `delete-process')
after it has failed. Still, this happens after the process has been
deactivated.

> I wonder what Emacs does for ":nowait t" without async DNS, when the
> connect fails. Iʼd expect it to call the sentinel with a "failed"
> status.

Is there a trivial way to test this?

Best,
Shawn




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Mon, 30 Jun 2025 08:03:02 GMT) Full text and rfc822 format available.

Message #26 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Robert Pluim <rpluim <at> gmail.com>
To: Shawn Henson <shawn <at> shenso.name>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Mon, 30 Jun 2025 10:01:50 +0200
>>>>> On Sun, 29 Jun 2025 17:22:36 -0400, Shawn Henson <shawn <at> shenso.name> said:

    Shawn> Robert Pluim <rpluim <at> gmail.com> writes:
    >>>>>>> On Sun, 29 Jun 2025 05:17:18 -0400, Shawn Henson <shawn <at> shenso.name> said:
    Shawn> I see, though, interestingly if you are to run the `list-processes'
    Shawn> you will see it persist there
    Shawn> indefinitely with a "failed" status.  And if you do kill it, then the
    Shawn> process sentinel will be
    Shawn> called.
    >> 
    >> Hmm, that seems wrong. When using async DNS, which we will only do for
    >> ":nowait t", Emacs will create the process, and then deactivate it
    >> upon DNS failure with a status of "failed". I donʼt think the sentinel
    >> gets called, but I havenʼt tested it.

    Shawn> Sorry, I miswrote, I said "killing", but I meant to say the sentinel only gets
    Shawn> called when *deleting* the process (manually, with `delete-process')
    Shawn> after it has failed. Still, this happens after the process has been
    Shawn> deactivated.

If the view is that we didnʼt call the sentinel because the DNS
failure means we didnʼt create a process, then we shouldnʼt call the
sentinel when we delete the process either.

    >> I wonder what Emacs does for ":nowait t" without async DNS, when the
    >> connect fails. Iʼd expect it to call the sentinel with a "failed"
    >> status.

    Shawn> Is there a trivial way to test this?

Not without recompiling Emacs, but Iʼve just tested it. It results in
an immediate error return from `make-network-process', no process is
created, and the sentinel is not called. Thatʼs all as expected (now
that Iʼve had my coffee 😀).

Eli, what can we do here? Whether or not Emacs is using getaddrinfo_a
should not affect the behaviour here, although having a process be
created is unavoidable, since weʼre deferring the DNS lookup.

The docstring for `make-network-process' says this in the :nowait
section:

    the sentinel function will be called with second arg matching
    "open" (if successful) or "failed" when the connect completes.

Pedantically, the `connect' syscall is not completed, since we never
attempt it because of the DNS failure. But the "attempt to connect to
the remote host" has completed, unsuccessfully, so we should call the
sentinel (and not call it when the process is deleted).

Robert
-- 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Mon, 30 Jun 2025 12:22:02 GMT) Full text and rfc822 format available.

Message #29 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Shawn Henson <shawn <at> shenso.name>
Cc: rpluim <at> gmail.com, 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Mon, 30 Jun 2025 15:20:53 +0300
> From: Shawn Henson <shawn <at> shenso.name>
> Cc: Eli Zaretskii <eliz <at> gnu.org>,  78920 <at> debbugs.gnu.org
> Date: Sun, 29 Jun 2025 17:22:36 -0400
> 
> Robert Pluim <rpluim <at> gmail.com> writes:
> 
> > I wonder what Emacs does for ":nowait t" without async DNS, when the
> > connect fails. Iʼd expect it to call the sentinel with a "failed"
> > status.
> 
> Is there a trivial way to test this?

Run the recipe on MS-Windows ;-)

The result is that we signal an error:

  Debugger entered--Lisp error: (error "thisisnotarealhostname/80 No such host is known. ")
    make-network-process(:name "dns-fail-test" :buffer "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait t :sentinel #f(lambda (process event) [t] (print event)))
    (let ((my-test-proc (make-network-process :name "dns-fail-test" :buffer "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait t :sentinel #'(lambda (process event) (print event))))) (message "process status: %s" (process-status my-test-proc)))
    (progn (let ((my-test-proc (make-network-process :name "dns-fail-test" :buffer "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait t :sentinel #'(lambda (process event) (print event))))) (message "process status: %s" (process-status my-test-proc))))
    eval((progn (let ((my-test-proc (make-network-process :name "dns-fail-test" :buffer "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait t :sentinel #'(lambda ... ...)))) (message "process status: %s" (process-status my-test-proc)))) t)

and there's no process shown by list-processes.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Mon, 30 Jun 2025 12:47:02 GMT) Full text and rfc822 format available.

Message #32 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Robert Pluim <rpluim <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Shawn Henson <shawn <at> shenso.name>, 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Mon, 30 Jun 2025 14:46:21 +0200
>>>>> On Mon, 30 Jun 2025 15:20:53 +0300, Eli Zaretskii <eliz <at> gnu.org> said:

    >> From: Shawn Henson <shawn <at> shenso.name>
    >> Cc: Eli Zaretskii <eliz <at> gnu.org>,  78920 <at> debbugs.gnu.org
    >> Date: Sun, 29 Jun 2025 17:22:36 -0400
    >> 
    >> Robert Pluim <rpluim <at> gmail.com> writes:
    >> 
    >> > I wonder what Emacs does for ":nowait t" without async DNS, when the
    >> > connect fails. Iʼd expect it to call the sentinel with a "failed"
    >> > status.
    >> 
    >> Is there a trivial way to test this?

    Eli> Run the recipe on MS-Windows ;-)

    Eli> The result is that we signal an error:

    Eli>   Debugger entered--Lisp error: (error "thisisnotarealhostname/80 No such host is known. ")
    Eli>     make-network-process(:name "dns-fail-test" :buffer "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait t :sentinel #f(lambda (process event) [t] (print event)))
    Eli>     (let ((my-test-proc (make-network-process :name "dns-fail-test" :buffer "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait t :sentinel #'(lambda (process event) (print event))))) (message "process status: %s" (process-status my-test-proc)))
    Eli>     (progn (let ((my-test-proc (make-network-process :name "dns-fail-test" :buffer "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait t :sentinel #'(lambda (process event) (print event))))) (message "process status: %s" (process-status my-test-proc))))
    Eli>     eval((progn (let ((my-test-proc (make-network-process :name "dns-fail-test" :buffer "dns-fail-test-buf" :host "thisisnotarealhostname" :service 80 :nowait t :sentinel #'(lambda ... ...)))) (message "process status: %s" (process-status my-test-proc)))) t)

    Eli> and there's no process shown by list-processes.

Yes, in retrospect that makes sense as a behaviour. But we canʼt do
that with async DNS + :nowait t. Something like the following perhaps?
Although I think the sentinel still gets called when you delete the
leftover process, so probably more is needed.

Robert
-- 

diff --git a/src/process.c b/src/process.c
index e61ec425f7e..473d8294a88 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5172,6 +5172,7 @@ check_for_dns (Lisp_Object proc)
 			concat3 (build_string ("Name lookup of "),
 				 build_string (p->dns_request->ar_name),
 				 build_string (" failed")))));
+      exec_sentinel (proc, build_string ("Name lookup failed\n"));
     }




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Mon, 30 Jun 2025 12:54:02 GMT) Full text and rfc822 format available.

Message #35 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Robert Pluim <rpluim <at> gmail.com>
Cc: shawn <at> shenso.name, 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Mon, 30 Jun 2025 15:52:45 +0300
> From: Robert Pluim <rpluim <at> gmail.com>
> Cc: Eli Zaretskii <eliz <at> gnu.org>,  78920 <at> debbugs.gnu.org
> Date: Mon, 30 Jun 2025 10:01:50 +0200
> 
> >>>>> On Sun, 29 Jun 2025 17:22:36 -0400, Shawn Henson <shawn <at> shenso.name> said:
> 
>     >> I wonder what Emacs does for ":nowait t" without async DNS, when the
>     >> connect fails. Iʼd expect it to call the sentinel with a "failed"
>     >> status.
> 
>     Shawn> Is there a trivial way to test this?
> 
> Not without recompiling Emacs, but Iʼve just tested it. It results in
> an immediate error return from `make-network-process', no process is
> created, and the sentinel is not called. Thatʼs all as expected (now
> that Iʼve had my coffee 😀).

Right.

> Eli, what can we do here? Whether or not Emacs is using getaddrinfo_a
> should not affect the behaviour here, although having a process be
> created is unavoidable, since weʼre deferring the DNS lookup.

If we want the same behavior, we should signal an error when DNS look
up fails.

> The docstring for `make-network-process' says this in the :nowait
> section:
> 
>     the sentinel function will be called with second arg matching
>     "open" (if successful) or "failed" when the connect completes.
> 
> Pedantically, the `connect' syscall is not completed, since we never
> attempt it because of the DNS failure. But the "attempt to connect to
> the remote host" has completed, unsuccessfully, so we should call the
> sentinel (and not call it when the process is deleted).

But then the behavior will not be like we get when getaddrinfo_a is
unavailable, no?

Technically, we have no process object in this case; the fact that we
create one is an implementation detail.  I'd even go as far as saying
that this "process" should not be exposed to Lisp.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Mon, 30 Jun 2025 13:13:03 GMT) Full text and rfc822 format available.

Message #38 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Robert Pluim <rpluim <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: shawn <at> shenso.name, 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Mon, 30 Jun 2025 15:12:48 +0200
>>>>> On Mon, 30 Jun 2025 15:52:45 +0300, Eli Zaretskii <eliz <at> gnu.org> said:

    >> Eli, what can we do here? Whether or not Emacs is using getaddrinfo_a
    >> should not affect the behaviour here, although having a process be
    >> created is unavoidable, since weʼre deferring the DNS lookup.

    Eli> If we want the same behavior, we should signal an error when DNS look
    Eli> up fails.

OK

    >> The docstring for `make-network-process' says this in the :nowait
    >> section:
    >> 
    >> the sentinel function will be called with second arg matching
    >> "open" (if successful) or "failed" when the connect completes.
    >> 
    >> Pedantically, the `connect' syscall is not completed, since we never
    >> attempt it because of the DNS failure. But the "attempt to connect to
    >> the remote host" has completed, unsuccessfully, so we should call the
    >> sentinel (and not call it when the process is deleted).

    Eli> But then the behavior will not be like we get when getaddrinfo_a is
    Eli> unavailable, no?

True. Then the semantics would be "we couldnʼt create a process
because DNS failed" in both cases (and the sentinel is not called). I
wonder if doing it the other way would be more in line with peopleʼs
expectations:

    `make-network-process' with :nowait t always succeeds, and if thereʼs
    a DNS failure the sentinel is called with an error.

After all, :nowait t is the caller asking for asynchronicity.

Either way, Emacsʼ behaviour changes.

    Eli> Technically, we have no process object in this case; the fact that we
    Eli> create one is an implementation detail.  I'd even go as far as saying
    Eli> that this "process" should not be exposed to Lisp.

Then weʼd need to split `make_process' between creating the C-level
process object, and adding that object to `Vprocess_alist' (I hope
that would be enough). And we have to expose it to Lisp in some form,
since `make-network-process' returns a process object.

Robert
-- 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Mon, 30 Jun 2025 13:37:02 GMT) Full text and rfc822 format available.

Message #41 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Robert Pluim <rpluim <at> gmail.com>
Cc: shawn <at> shenso.name, 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Mon, 30 Jun 2025 16:36:24 +0300
> From: Robert Pluim <rpluim <at> gmail.com>
> Cc: shawn <at> shenso.name,  78920 <at> debbugs.gnu.org
> Date: Mon, 30 Jun 2025 15:12:48 +0200
> 
> >>>>> On Mon, 30 Jun 2025 15:52:45 +0300, Eli Zaretskii <eliz <at> gnu.org> said:
> 
>     >> Eli, what can we do here? Whether or not Emacs is using getaddrinfo_a
>     >> should not affect the behaviour here, although having a process be
>     >> created is unavoidable, since weʼre deferring the DNS lookup.
> 
>     Eli> If we want the same behavior, we should signal an error when DNS look
>     Eli> up fails.
> 
> OK
> 
>     >> The docstring for `make-network-process' says this in the :nowait
>     >> section:
>     >> 
>     >> the sentinel function will be called with second arg matching
>     >> "open" (if successful) or "failed" when the connect completes.
>     >> 
>     >> Pedantically, the `connect' syscall is not completed, since we never
>     >> attempt it because of the DNS failure. But the "attempt to connect to
>     >> the remote host" has completed, unsuccessfully, so we should call the
>     >> sentinel (and not call it when the process is deleted).
> 
>     Eli> But then the behavior will not be like we get when getaddrinfo_a is
>     Eli> unavailable, no?
> 
> True. Then the semantics would be "we couldnʼt create a process
> because DNS failed" in both cases (and the sentinel is not called). I
> wonder if doing it the other way would be more in line with peopleʼs
> expectations:
> 
>     `make-network-process' with :nowait t always succeeds, and if thereʼs
>     a DNS failure the sentinel is called with an error.
> 
> After all, :nowait t is the caller asking for asynchronicity.
> 
> Either way, Emacsʼ behaviour changes.
> 
>     Eli> Technically, we have no process object in this case; the fact that we
>     Eli> create one is an implementation detail.  I'd even go as far as saying
>     Eli> that this "process" should not be exposed to Lisp.
> 
> Then weʼd need to split `make_process' between creating the C-level
> process object, and adding that object to `Vprocess_alist' (I hope
> that would be enough). And we have to expose it to Lisp in some form,
> since `make-network-process' returns a process object.

We could give the process a special attribute, and make Lisp APIs skip
it.

But maybe calling the sentinel will be easier and less drastic?  We
just need to document that the behavior is not identical to the
systems where async DNS resolution is unavailable.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#78920; Package emacs. (Mon, 30 Jun 2025 15:21:02 GMT) Full text and rfc822 format available.

Message #44 received at 78920 <at> debbugs.gnu.org (full text, mbox):

From: Robert Pluim <rpluim <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: shawn <at> shenso.name, 78920 <at> debbugs.gnu.org
Subject: Re: bug#78920: 30.1; Process sentinel is not called when DNS lookup
 fails
Date: Mon, 30 Jun 2025 17:20:02 +0200
>>>>> On Mon, 30 Jun 2025 16:36:24 +0300, Eli Zaretskii <eliz <at> gnu.org> said:
    Eli> Technically, we have no process object in this case; the fact that we
    Eli> create one is an implementation detail.  I'd even go as far as saying
    Eli> that this "process" should not be exposed to Lisp.
    >> 
    >> Then weʼd need to split `make_process' between creating the C-level
    >> process object, and adding that object to `Vprocess_alist' (I hope
    >> that would be enough). And we have to expose it to Lisp in some form,
    >> since `make-network-process' returns a process object.

    Eli> We could give the process a special attribute, and make Lisp APIs skip
    Eli> it.

I think that comes down to the same thing as not adding it to
Vprocess_alist until DNS has succeeded, which is easy to do, Iʼd just
have to make sure it gets added to Vprocess_alist at all the right
spots.

    Eli> But maybe calling the sentinel will be easier and less drastic?  We
    Eli> just need to document that the behavior is not identical to the
    Eli> systems where async DNS resolution is unavailable.

Thereʼs a third DNS failure case I just noticed. With :nowait t we can
get

1. An immediate failure of async DNS
2. A delayed failure of async DNS
3. An immediate failure of sync DNS

In cases 1 and 3 we return an error, in case 2 we set the process
status to "failed". The sentinel is never called.

So calling the sentinel in case 2 changes the behaviour, but that
behaviour was already different, and then it would match what happens
if the remote host exists but eg rejects the connection.

The semantics are not really documented, so I guess we can change them
🙂

Robert
-- 




This bug report was last modified 4 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.