Announcements and discussions for Gnus, the GNU Emacs Usenet newsreader
 help / color / mirror / Atom feed
* Mail source unreachable - continue yes/no?
@ 2021-10-11  6:07 Lars-Johan Liman
  2021-10-12 12:39 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars-Johan Liman @ 2021-10-11  6:07 UTC (permalink / raw)
  To: info-gnus-english

Hi!

I have used Gnus for mail for many a good year, and I have several mail
sources. One of them is only reachable if I access it over VPN. (Don't
ask!) Occasionally I forget to enable the VPN before accessing my mail,
and the attempt to pick up mail from that particular server will fail.
Fair enough, my problem.

But when that happens, the mail-fetching process interrupts itself and I
get a follow-up question from GNUS, along the lines of ...

    Mail source (imap :server xxx.xxx :stream tls :authentication ...)
    error (IMAP error: nil). Continue? (yes or no)

It seems to make no difference what so ever whether I answer yes or no
to the question. Regardless of which, Gnus will continue to fetch mail
from the next source from the list in my mail-sources variable.

My question: how is my answer (yes/no) used? (Which are the consequences
of responding yes or no, respectively?)

				Best regards,
				  /Liman


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-11  6:07 Mail source unreachable - continue yes/no? Lars-Johan Liman
@ 2021-10-12 12:39 ` Lars Ingebrigtsen
  2021-10-12 16:50   ` Eric Abrahamsen
  2021-10-12 16:57   ` Lars-Johan Liman
  0 siblings, 2 replies; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-12 12:39 UTC (permalink / raw)
  To: Lars-Johan Liman; +Cc: info-gnus-english

Lars-Johan Liman <liman@cafax.se> writes:

> My question: how is my answer (yes/no) used? (Which are the consequences
> of responding yes or no, respectively?)

Answering "no" should beep an error, say "Cannot get new mail" and then
stop.  Hm...  but I see that the caller (in `nnmail-get-new-mail-1' just
ignores that, and carries on as if nothing happened), so it doesn't
matter whatever you respond.

Hm...  I'm not sure how to fix this, or what the right fix would be
here.  Anybody got an opinion?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 12:39 ` Lars Ingebrigtsen
@ 2021-10-12 16:50   ` Eric Abrahamsen
  2021-10-12 16:57     ` Lars Ingebrigtsen
  2021-10-12 16:57   ` Lars-Johan Liman
  1 sibling, 1 reply; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-12 16:50 UTC (permalink / raw)
  To: info-gnus-english

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Lars-Johan Liman <liman@cafax.se> writes:
>
>> My question: how is my answer (yes/no) used? (Which are the consequences
>> of responding yes or no, respectively?)
>
> Answering "no" should beep an error, say "Cannot get new mail" and then
> stop.  Hm...  but I see that the caller (in `nnmail-get-new-mail-1' just
> ignores that, and carries on as if nothing happened), so it doesn't
> matter whatever you respond.
>
> Hm...  I'm not sure how to fix this, or what the right fix would be
> here.  Anybody got an opinion?

I have an opinion :)

We create a few custom error symbols for backend errors, including mail
source failures, open-server failures, etc, and we put some
condition-cases handling those errors in `gnus-get-unread-articles'.
They collect the errors, continue with the next server, and at the end
of the process display a nice tidy message indicating which servers
failed to connect.

It's always been a bit annoying that an nntp connection failure hoses
the entire update process.

WDYT?

Eric



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 16:50   ` Eric Abrahamsen
@ 2021-10-12 16:57     ` Lars Ingebrigtsen
  2021-10-12 17:49       ` Eric Abrahamsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-12 16:57 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: info-gnus-english

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> We create a few custom error symbols for backend errors, including mail
> source failures, open-server failures, etc, and we put some
> condition-cases handling those errors in `gnus-get-unread-articles'.

This is called from nnmail-get-new-mail-1, though, which ignores errors
on its own.  `gnus-get-unread-articles' also has error-ignoring
capabilities and...

> They collect the errors, continue with the next server, and at the end
> of the process display a nice tidy message indicating which servers
> failed to connect.

... does just that, I think?  At least that's what happens when a server
fails for me.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 12:39 ` Lars Ingebrigtsen
  2021-10-12 16:50   ` Eric Abrahamsen
@ 2021-10-12 16:57   ` Lars-Johan Liman
  2021-10-14 17:39     ` Eric Abrahamsen
  1 sibling, 1 reply; 23+ messages in thread
From: Lars-Johan Liman @ 2021-10-12 16:57 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: info-gnus-english

Lol!

Thanks. OK, so I wasn't off the mark, then. :-)

I'm not even sure this needs to be fixed. It's good that the fact that
the server couldn't be reached is signalled, but continuing seems like
the right thing to do. The message is somewhat misleading though. How
about changing the "question" to a "Please ack!" of some kind?

				Cheers,
				  /Liman

larsi@gnus.org 2021-10-12 14:39 [+0200]:
> Lars-Johan Liman <liman@cafax.se> writes:

>> My question: how is my answer (yes/no) used? (Which are the consequences
>> of responding yes or no, respectively?)

> Answering "no" should beep an error, say "Cannot get new mail" and then
> stop.  Hm...  but I see that the caller (in `nnmail-get-new-mail-1' just
> ignores that, and carries on as if nothing happened), so it doesn't
> matter whatever you respond.

> Hm...  I'm not sure how to fix this, or what the right fix would be
> here.  Anybody got an opinion?

> -- 
> (domestic pets only, the antidote for overdose, milk.)
>    bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 16:57     ` Lars Ingebrigtsen
@ 2021-10-12 17:49       ` Eric Abrahamsen
  2021-10-12 17:56         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-12 17:49 UTC (permalink / raw)
  To: info-gnus-english

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> We create a few custom error symbols for backend errors, including mail
>> source failures, open-server failures, etc, and we put some
>> condition-cases handling those errors in `gnus-get-unread-articles'.
>
> This is called from nnmail-get-new-mail-1, though, which ignores errors
> on its own.  `gnus-get-unread-articles' also has error-ignoring
> capabilities and...

`nnmail-get-new-mail' is called from within `gnus-request-scan', and
there's no error ignoring around `gnus-request-scan' in
`gnus-get-unread-articles' -- is there? I can't see anything. I would
propose removing error handling from `nnmail-get-new-mail-1': if the
fetching of mail sources well and truly fails (and the user hits "no" to
give up on the process), it should just signal an error up the line.

>> They collect the errors, continue with the next server, and at the end
>> of the process display a nice tidy message indicating which servers
>> failed to connect.
>
> ... does just that, I think?  At least that's what happens when a server
> fails for me.

I think nntp servers are louder than the others. When I hit "g" and the
nntp connection times out, I get a "server closed connection" message,
and the whole update process halts.



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 17:49       ` Eric Abrahamsen
@ 2021-10-12 17:56         ` Lars Ingebrigtsen
  2021-10-12 18:18           ` Eric Abrahamsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-12 17:56 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: info-gnus-english

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> `nnmail-get-new-mail' is called from within `gnus-request-scan', and
> there's no error ignoring around `gnus-request-scan' in
> `gnus-get-unread-articles' -- is there? I can't see anything. I would
> propose removing error handling from `nnmail-get-new-mail-1': if the
> fetching of mail sources well and truly fails (and the user hits "no" to
> give up on the process), it should just signal an error up the line.

Yes, I think so...  but isn't there error handling in gnus-request-scan?
I really thought there was...

> I think nntp servers are louder than the others. When I hit "g" and the
> nntp connection times out, I get a "server closed connection" message,
> and the whole update process halts.

That sounds like a bug.  :-)  If I push, for instance

	(nntp "localhost")

to gnus-secondary-select-methods and hit g, I get an error message and
then the server is marked as "denied", but Gnus carries on its merry
way.  (Same if something times out or I hit `C-g' while it's connecting.)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 17:56         ` Lars Ingebrigtsen
@ 2021-10-12 18:18           ` Eric Abrahamsen
  2021-10-12 18:25             ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-12 18:18 UTC (permalink / raw)
  To: info-gnus-english

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> `nnmail-get-new-mail' is called from within `gnus-request-scan', and
>> there's no error ignoring around `gnus-request-scan' in
>> `gnus-get-unread-articles' -- is there? I can't see anything. I would
>> propose removing error handling from `nnmail-get-new-mail-1': if the
>> fetching of mail sources well and truly fails (and the user hits "no" to
>> give up on the process), it should just signal an error up the line.
>
> Yes, I think so...  but isn't there error handling in gnus-request-scan?
> I really thought there was...

You mean in `gnus-get-unread-articles', around `gnus-request-scan'? No,
there doesn't seem to be.

In other places where `gnus-request-scan' is called, the code is mostly
working with a single group, in which case you could argue that errors
should just bubble up to the user.

>> I think nntp servers are louder than the others. When I hit "g" and the
>> nntp connection times out, I get a "server closed connection" message,
>> and the whole update process halts.
>
> That sounds like a bug.  :-)  If I push, for instance
>
> 	(nntp "localhost")
>
> to gnus-secondary-select-methods and hit g, I get an error message and
> then the server is marked as "denied", but Gnus carries on its merry
> way.  (Same if something times out or I hit `C-g' while it's connecting.)

I've got my nntp server set in `gnus-select-method', maybe that's why?
This has annoyed me off and on for years but I've never taken the time
to look into it. My other servers are all localhost nnimap and I never
see errors there. I just set debug-on-message appropriately, and will
figure out exactly where things are going off.



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 18:18           ` Eric Abrahamsen
@ 2021-10-12 18:25             ` Lars Ingebrigtsen
  2021-10-12 19:50               ` Eric Abrahamsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-12 18:25 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: info-gnus-english

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> I've got my nntp server set in `gnus-select-method', maybe that's why?
> This has annoyed me off and on for years but I've never taken the time
> to look into it. My other servers are all localhost nnimap and I never
> see errors there. I just set debug-on-message appropriately, and will
> figure out exactly where things are going off.

Tried

(setq gnus-select-method '(nntp "localhost"))

and that worked fine, too.  There's probably errors that aren't
handled well, but there's infrastructure to collect all the erroring
backends and display the errors at the end.  Well, at least there used
to be; haven't actually looked at the code now.  :-)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 18:25             ` Lars Ingebrigtsen
@ 2021-10-12 19:50               ` Eric Abrahamsen
  2021-10-13 11:33                 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-12 19:50 UTC (permalink / raw)
  To: info-gnus-english

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> I've got my nntp server set in `gnus-select-method', maybe that's why?
>> This has annoyed me off and on for years but I've never taken the time
>> to look into it. My other servers are all localhost nnimap and I never
>> see errors there. I just set debug-on-message appropriately, and will
>> figure out exactly where things are going off.
>
> Tried
>
> (setq gnus-select-method '(nntp "localhost"))
>
> and that worked fine, too.  There's probably errors that aren't
> handled well, but there's infrastructure to collect all the erroring
> backends and display the errors at the end.  Well, at least there used
> to be; haven't actually looked at the code now.  :-)

I put plain old calls to `error' inside `nnimap-request-scan', and that
also derailed the "g" update process. So whatever handling there once
was either is not around this particular piece of code, or else it might
have gone away at some point.

I had had `nntp-connection-timeout' set to 6, as it hangs indefinitely
otherwise. I stuck a call to `error' inside `nntp-report'; so far I
can't get an actual backtrace, I guess because there _is_ error handling
for nntp. But even there I don't think it's "flow control" handling, it
appears to just be error demotion.

Are you likely to recall further how this once worked? :) I can start
sketching out some custom errors, otherwise.

Eric



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 19:50               ` Eric Abrahamsen
@ 2021-10-13 11:33                 ` Lars Ingebrigtsen
  2021-10-14  5:03                   ` Eric Abrahamsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-13 11:33 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: info-gnus-english

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> I put plain old calls to `error' inside `nnimap-request-scan', and that
> also derailed the "g" update process. So whatever handling there once
> was either is not around this particular piece of code, or else it might
> have gone away at some point.

Yeah, perhaps it went missing at some point.

> Are you likely to recall further how this once worked? :) I can start
> sketching out some custom errors, otherwise.

I'm not sure about anything.  I do recall (in the olden days) getting a
humongous appended error message from all the backends if the network
went down or something, though.

Custom errors sound good, though.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-13 11:33                 ` Lars Ingebrigtsen
@ 2021-10-14  5:03                   ` Eric Abrahamsen
  2021-10-14 11:22                     ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-14  5:03 UTC (permalink / raw)
  To: info-gnus-english

[-- Attachment #1: Type: text/plain, Size: 4149 bytes --]

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> I put plain old calls to `error' inside `nnimap-request-scan', and that
>> also derailed the "g" update process. So whatever handling there once
>> was either is not around this particular piece of code, or else it might
>> have gone away at some point.
>
> Yeah, perhaps it went missing at some point.
>
>> Are you likely to recall further how this once worked? :) I can start
>> sketching out some custom errors, otherwise.
>
> I'm not sure about anything.  I do recall (in the olden days) getting a
> humongous appended error message from all the backends if the network
> went down or something, though.

On second thought you're not wrong here: the various *-open-server
deffoos report their own failures with `nnheader-report' instead of
signaling errors, and then `gnus-open-server' swallows any other errors
and converts them to messages.

Failures arrived at via `gnus-request-scan' mostly show up as actual
errors.

I still haven't looked into why nntp-connection-timeout ends up
interrupting everything.

> Custom errors sound good, though.

Okay, here's a _very_ rough first sketch. There are a handful of errors
defined, mostly for connection problems. I didn't do any handling for
authentication failures, because that's a fairly distinct system, and
I'm not sure there's any need to mess with it (I haven't tested what
auth failures do to Gnus update), anyway that can be left for later.

A few things happen in this patch:

- When the gnus-open-server deffoo processes fail, they (or their
  downstream functions) signal 'gnus-server-connection-error. (I didn't
  go through and do this for every backend, just enough to get the
  idea.)
- Mail source fetching can fail, in which case 'gnus-mail-source-error
  is signaled. nnmail.el no longer handles this error: it propagates up
  and out through gnus-request-scan.
- There are `condition-case' wrappers in `gnus-get-unread-articles' now,
  which seems to be the main place where it's important not to interrupt
  a larger loop. Most other places the user is just "doing one thing",
  and it seems okay to let the error reach them directly.

Some observations and questions:

- There are many places and depth-levels in Gnus where failure modes are
  dealt with as messages (in effect working like `with-demoted-errors')
  or as nil return values from functions, which are then converted into
  messages, or sometimes even re-signaled as an actual `error' with a
  new message string. This often ends up burying real errors, and/or
  making debug on error hard to use. We could try flattening this out:
  low-level functions signal errors, and only top-level functions in
  gnus-start/gnus-group/gnus-sum get to catch them at the last minute,
  and only if necessary (other layers can of course catch and re-signal
  the errors if some cleanup work needs to be done). I have no idea if
  this would end up working out, but I think it would be good to try.
  And more use of `condition-case-unless-debug' at the top level.

- There are many ways of logging, and messaging the user. Apart from
  `message' itself, there's `nnheader-report', `gnus-backend-trace',
  `nnheader-message(-maybe)', `gnus-message' and its action message log,
  along with `gnus-final-warning' and `gnus-error'.

  nnheader-report, in particular, seems to often be used as a substitute
  for actually signaling an error. A server is asked to do something, it
  fails for some reason and logs the reason with nnheader-report, then
  returns nil. The caller sees the nil, then retrieves the string with
  nnheader-get-report, and uses it to signal an error.

  I'm not claiming to have thought this through completely, much less
  tested anything, but I wonder if in most cases the underlying code
  couldn't just signal an error directly.

- Lastly, I wanted to try out the warning facilities here, just to see
  if they might provide a good tool.
  nnheader-message/gnus-message/gnus-error could dispatch to
  display-warning.

Anyway, those are some thoughts that occurred while poking around with
this.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gnus-define-errors.diff --]
[-- Type: text/x-patch, Size: 13863 bytes --]

diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 606bd3a39a..3c1387b73f 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -45,6 +45,14 @@ gnus-agent-file-loading-local
 (defvar gnus-agent-file-loading-cache)
 (defvar gnus-topic-alist)
 
+(define-error 'gnus-error "Gnus error")
+(define-error 'gnus-mail-source-error
+  "Gnus mail source error" 'gnus-error)
+(define-error 'gnus-server-error
+  "Gnus server error" 'gnus-error)
+(define-error 'gnus-server-connection-error
+  "Error connecting to server" 'gnus-server-error)
+
 (defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc")
   "Your `.newsrc' file.
 `.newsrc-SERVER' will be used instead if that exists."
@@ -1604,7 +1612,8 @@ gnus-get-unread-articles
 	 (gnus-agent-article-local-times 0)
 	 (archive-method (gnus-server-to-method "archive"))
 	 info group active method cmethod
-	 method-type method-group-list entry)
+	 method-type method-group-list entry
+         failed-methods)
     (gnus-message 6 "Checking new news...")
 
     (while newsrc
@@ -1685,8 +1694,11 @@ gnus-get-unread-articles
 			    gnus-secondary-select-methods))
 	(when (and (not (assoc method type-cache))
 		   (gnus-check-backend-function 'request-list (car method)))
-	  (with-current-buffer nntp-server-buffer
-	    (gnus-read-active-file-1 method nil)))))
+          (condition-case-unless-debug err
+	      (with-current-buffer nntp-server-buffer
+	        (gnus-read-active-file-1 method nil))
+            (gnus-server-connection-error
+             (push (cons method err) failed-methods))))))
 
     ;; Clear out all the early methods.
     (dolist (elem type-cache)
@@ -1697,11 +1709,15 @@ gnus-get-unread-articles
 		    'retrieve-group-data-early (car method))
 		   (not (gnus-method-denied-p method)))
 	  (when (ignore-errors (gnus-get-function method 'open-server))
-	    (unless (gnus-server-opened method)
-	      (gnus-open-server method))
-	    (when (gnus-server-opened method)
-	      ;; Just mark this server as "cleared".
-	      (gnus-retrieve-group-data-early method nil))))))
+            (condition-case-unless-debug err
+	        (progn
+                  (unless (gnus-server-opened method)
+	            (gnus-open-server method))
+	          ;; Just mark this server as "cleared".
+	          (gnus-retrieve-group-data-early method nil))
+              (gnus-server-connection-error
+               (push (cons method err) failed-methods)
+               (setq type-cache (delq elem type-cache))))))))
 
     ;; Start early async retrieval of data.
     (let ((done-methods nil)
@@ -1725,7 +1741,6 @@ gnus-get-unread-articles
 		     ;; be unique at this point, but apparently it
 		     ;; does happen in the wild with some setups.
 		     (not (member sanity-spec done-methods))
-		     (gnus-server-opened method)
 		     (gnus-check-backend-function
 		      'retrieve-group-data-early (car method)))
 		(push sanity-spec done-methods)
@@ -1744,12 +1759,23 @@ gnus-get-unread-articles
 	  (let ((updatep (gnus-check-backend-function
 			  'request-update-info (car method))))
 	    ;; See if any of the groups from this method require updating.
-	    (gnus-read-active-for-groups method infos early-data)
-	    (dolist (info infos)
-	      (inline (gnus-get-unread-articles-in-group
-		       info (gnus-active (gnus-info-group info))
-		       updatep)))))))
-    (gnus-message 6 "Checking new news...done")))
+            (condition-case-unless-debug err
+                (progn
+	          (gnus-read-active-for-groups method infos early-data)
+	          (dolist (info infos)
+	            (inline (gnus-get-unread-articles-in-group
+		             info (gnus-active (gnus-info-group info))
+		             updatep))))
+              ((gnus-server-connection-error gnus-mail-source-error)
+               (push (cons method err) failed-methods)))))))
+    (gnus-message 6 "Checking new news...done")
+    (when failed-methods
+      (let ((warning-series t))
+        (dolist (m failed-methods)
+          (delay-warning
+           '(gnus)
+           (format "Failed to open %s: %S" (car m) (cdr m))
+           :error "*Gnus Warnings*"))))))
 
 (defun gnus-method-rank (type method)
   (cond
diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el
index af0a198376..2515a4261a 100644
--- a/lisp/gnus/mail-source.el
+++ b/lisp/gnus/mail-source.el
@@ -549,13 +549,10 @@ mail-source-fetch
 			   callback mail-source-crash-box))
 	      (mail-source-delete-crash-box))
 	    (+ found
-	       (if (or debug-on-quit debug-on-error)
+	       (condition-case-unless-debug err
 		   (funcall function source callback)
-		 (condition-case err
-		     (funcall function source callback)
-		   (error
-		    (if (and (not mail-source-ignore-errors)
-			     (not
+		 (error
+		  (unless (or mail-source-ignore-errors
 			      (yes-or-no-p
 			       (format "Mail source %s error (%s).  Continue? "
 				       (if (memq ':password source)
@@ -563,10 +560,10 @@ mail-source-fetch
 					     (setcar (cdr (memq ':password s))
 						     "********")
 					     s)
-					 source)
-				       (cadr err)))))
-		      (error "Cannot get new mail"))
-		    0)))))))))
+				         source)
+				       (cadr err))))
+		    (signal 'gnus-mail-source-error (list source err)))
+		  0))))))))
 
 (declare-function gnus-message "gnus-util" (level &rest args))
 
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 8a2acf6459..3305b6edd2 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -456,9 +456,7 @@ nnimap-open-connection
 		   while (eq stream 'no-connect)
 		   finally (return stream))
 	   (nnimap-open-connection-1 buffer))))
-    (if (eq stream 'no-connect)
-	nil
-      stream)))
+    stream))
 
 ;; This is only needed for Windows XP or earlier
 (defun nnimap-map-port (port)
@@ -534,7 +532,8 @@ nnimap-open-connection-1
 	    (progn
 	      (nnheader-report 'nnimap "Unable to contact %s:%s via %s"
 			       nnimap-address (car ports) nnimap-stream)
-	      'no-connect)
+	      (signal 'gnus-server-connection-error
+                      (list nnimap-object)))
 	  (set-process-query-on-exit-flag stream nil)
 	  (if (not (string-match-p "[*.] \\(OK\\|PREAUTH\\)" greeting))
 	      (nnheader-report 'nnimap "%s" greeting)
diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el
index bcf01cfa9e..1a9258273c 100644
--- a/lisp/gnus/nnmail.el
+++ b/lisp/gnus/nnmail.el
@@ -1825,25 +1825,22 @@ nnmail-get-new-mail-1
       ;; and fetch the mail from each.
       (while (setq source (pop fetching-sources))
 	(when (setq new
-		    (condition-case cond
-			(mail-source-fetch
-			 source
-			 (let ((smsym (intern (format "%s-save-mail" method)))
+		    (or (mail-source-fetch
+		         source
+		         (let ((smsym (intern (format "%s-save-mail" method)))
 			       (ansym (intern (format "%s-active-number" method)))
 			       (src source))
-			   (lambda (file orig-file)
+		           (lambda (file orig-file)
 			     (nnmail-split-incoming
 			      file smsym
 			      spool-func
 			      (or in-group
-				  (if (equal file orig-file)
+			          (if (equal file orig-file)
 				      nil
 				    (nnmail-get-split-group orig-file
 							    src)))
 			      ansym))))
-		      ((error quit)
-		       (message "Mail source %s failed: %s" source cond)
-		       0)))
+                        0))
 	  (cl-incf total new)
 	  (cl-incf i)))
       ;; If we did indeed read any incoming spools, we save all info.
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el
index 690761a2d6..8d2b8d4cef 100644
--- a/lisp/gnus/nnmaildir.el
+++ b/lisp/gnus/nnmaildir.el
@@ -670,63 +670,65 @@ nnmaildir-open-server
   (let ((server (alist-get server-string nnmaildir--servers
 			   nil nil #'equal))
 	dir size x)
-    (catch 'return
-      (if server
-	  (and (nnmaildir--srv-groups server)
-	       (setq nnmaildir--cur-server server)
-	       (throw 'return t))
-	(setq server (make-nnmaildir--srv :address server-string))
-	(let ((inhibit-quit t))
-	  (setf (alist-get server-string nnmaildir--servers
-			   nil nil #'equal)
-		server)))
-      (setq dir (assq 'directory defs))
-      (unless dir
-	(setf (nnmaildir--srv-error server)
-	      "You must set \"directory\" in the select method")
-	(throw 'return nil))
-      (setq dir (cadr dir)
-	    dir (eval dir t)	;FIXME: Why `eval'?
-	    dir (expand-file-name dir)
-	    dir (file-name-as-directory dir))
-      (unless (file-exists-p dir)
-	(setf (nnmaildir--srv-error server) (concat "No such directory: " dir))
-	(throw 'return nil))
-      (setf (nnmaildir--srv-dir server) dir)
-      (setq x (assq 'directory-files defs))
-      (if (null x)
-	  (setq x (if nnheader-directory-files-is-safe 'directory-files
-		    'nnheader-directory-files-safe))
-	(setq x (cadr x))
-	(unless (functionp x)
-	  (setf (nnmaildir--srv-error server)
-		(concat "Not a function: " (prin1-to-string x)))
-	  (throw 'return nil)))
-      (setf (nnmaildir--srv-ls server) x)
-      (setq size (length (funcall x dir nil "\\`[^.]" 'nosort)))
-      (and (setq x (assq 'get-new-mail defs))
-	   (setq x (cdr x))
-	   (car x)
-	   (setf (nnmaildir--srv-gnm server) t)
-	   (require 'nnmail))
-      (setq x (assq 'target-prefix defs))
-      (if x
-	  (progn
-	    (setq x (cadr x)
-		  x (eval x t))	;FIXME: Why `eval'?
-	    (setf (nnmaildir--srv-target-prefix server) x))
-	(setq x (assq 'create-directory defs))
-	(if x
-	    (progn
-	      (setq x (cadr x)
-		    x (eval x t) ;FIXME: Why `eval'?
-		    x (file-name-as-directory x))
-	      (setf (nnmaildir--srv-target-prefix server) x))
-	  (setf (nnmaildir--srv-target-prefix server) "")))
-      (setf (nnmaildir--srv-groups server)
-	    (gnus-make-hashtable size))
-      (setq nnmaildir--cur-server server)
-      t)))
+    (unless
+	(catch 'return
+	  (if server
+	      (and (nnmaildir--srv-groups server)
+		   (setq nnmaildir--cur-server server)
+		   (throw 'return t))
+	    (setq server (make-nnmaildir--srv :address server-string))
+	    (let ((inhibit-quit t))
+	      (setf (alist-get server-string nnmaildir--servers
+			       nil nil #'equal)
+		    server)))
+	  (setq dir (assq 'directory defs))
+	  (unless dir
+	    (setf (nnmaildir--srv-error server)
+		  "You must set \"directory\" in the select method")
+	    (throw 'return nil))
+	  (setq dir (cadr dir)
+		dir (eval dir t)	;FIXME: Why `eval'?
+		dir (expand-file-name dir)
+		dir (file-name-as-directory dir))
+	  (unless (file-exists-p dir)
+	    (setf (nnmaildir--srv-error server) (concat "No such directory: " dir))
+	    (throw 'return nil))
+	  (setf (nnmaildir--srv-dir server) dir)
+	  (setq x (assq 'directory-files defs))
+	  (if (null x)
+	      (setq x (if nnheader-directory-files-is-safe 'directory-files
+			'nnheader-directory-files-safe))
+	    (setq x (cadr x))
+	    (unless (functionp x)
+	      (setf (nnmaildir--srv-error server)
+		    (concat "Not a function: " (prin1-to-string x)))
+	      (throw 'return nil)))
+	  (setf (nnmaildir--srv-ls server) x)
+	  (setq size (length (funcall x dir nil "\\`[^.]" 'nosort)))
+	  (and (setq x (assq 'get-new-mail defs))
+	       (setq x (cdr x))
+	       (car x)
+	       (setf (nnmaildir--srv-gnm server) t)
+	       (require 'nnmail))
+	  (setq x (assq 'target-prefix defs))
+	  (if x
+	      (progn
+		(setq x (cadr x)
+		      x (eval x t))	;FIXME: Why `eval'?
+		(setf (nnmaildir--srv-target-prefix server) x))
+	    (setq x (assq 'create-directory defs))
+	    (if x
+		(progn
+		  (setq x (cadr x)
+			x (eval x t)	;FIXME: Why `eval'?
+			x (file-name-as-directory x))
+		  (setf (nnmaildir--srv-target-prefix server) x))
+	      (setf (nnmaildir--srv-target-prefix server) "")))
+	  (setf (nnmaildir--srv-groups server)
+		(gnus-make-hashtable size))
+	  (setq nnmaildir--cur-server server)
+	  t)
+      (signal 'gnus-server-connection-error (list server)))))
 
 (defun nnmaildir--parse-filename (file)
   (let ((prefix (car file))
diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el
index 18acc73aad..98cbe79e8b 100644
--- a/lisp/gnus/nnml.el
+++ b/lisp/gnus/nnml.el
@@ -163,17 +163,18 @@ nnml-open-server
   (nnoo-change-server 'nnml server defs)
   (when (not (file-exists-p nnml-directory))
     (ignore-errors (make-directory nnml-directory t)))
-  (cond
-   ((not (file-exists-p nnml-directory))
-    (nnml-close-server)
-    (nnheader-report 'nnml "Couldn't create directory: %s" nnml-directory))
-   ((not (file-directory-p (file-truename nnml-directory)))
-    (nnml-close-server)
-    (nnheader-report 'nnml "Not a directory: %s" nnml-directory))
-   (t
-    (nnheader-report 'nnml "Opened server %s using directory %s"
-		     server nnml-directory)
-    t)))
+  (let (msg)
+    (if (or (and (not (file-exists-p nnml-directory))
+                 (setq msg "Couldn't create directory: %s"))
+            (and (not (file-directory-p (file-truename nnml-directory)))
+                 (setq msg "Not a directory: %s")))
+        (progn
+          (nnml-close-server)
+          (nnheader-report 'nnml msg nnml-directory)
+          (signal 'gnus-server-connection-error (list server)))
+      (nnheader-report 'nnml "Opened server %s using directory %s"
+		       server nnml-directory)
+      t)))
 
 (deffoo nnml-request-regenerate (server)
   (nnml-possibly-change-directory nil server)
diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el
index 615a3c931b..2f8b271c55 100644
--- a/lisp/gnus/nntp.el
+++ b/lisp/gnus/nntp.el
@@ -1296,7 +1296,8 @@ nntp-open-connection
 	(goto-char (point-min))
 	(nnheader-report 'nntp "Error when connecting: %s"
 			 (buffer-substring (point) (line-end-position))))
-      (setq process nil))
+      (setq process nil)
+      (signal 'gnus-server-connection-error (list nntp-address)))
     (unless process
       (nntp-kill-buffer pbuffer))
     (when (and (buffer-live-p pbuffer)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-14  5:03                   ` Eric Abrahamsen
@ 2021-10-14 11:22                     ` Lars Ingebrigtsen
  2021-10-14 18:31                       ` Eric Abrahamsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-14 11:22 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: info-gnus-english

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> On second thought you're not wrong here: the various *-open-server
> deffoos report their own failures with `nnheader-report' instead of
> signaling errors, and then `gnus-open-server' swallows any other errors
> and converts them to messages.

Ah.  I knew there was something like that somewhere.  :-)

> Failures arrived at via `gnus-request-scan' mostly show up as actual
> errors.

Perhaps we should adjust those errors to be nnheader-report thingies
instead?

> - When the gnus-open-server deffoo processes fail, they (or their
>   downstream functions) signal 'gnus-server-connection-error. (I didn't
>   go through and do this for every backend, just enough to get the
>   idea.)
> - Mail source fetching can fail, in which case 'gnus-mail-source-error
>   is signaled. nnmail.el no longer handles this error: it propagates up
>   and out through gnus-request-scan.

I've just skimmed the patch, but the approach looks sound to me (in
general).

> Some observations and questions:
>
> - There are many places and depth-levels in Gnus where failure modes are
>   dealt with as messages (in effect working like `with-demoted-errors')
>   or as nil return values from functions, which are then converted into
>   messages, or sometimes even re-signaled as an actual `error' with a
>   new message string. This often ends up burying real errors, and/or
>   making debug on error hard to use. We could try flattening this out:
>   low-level functions signal errors, and only top-level functions in
>   gnus-start/gnus-group/gnus-sum get to catch them at the last minute,
>   and only if necessary (other layers can of course catch and re-signal
>   the errors if some cleanup work needs to be done). I have no idea if
>   this would end up working out, but I think it would be good to try.
>   And more use of `condition-case-unless-debug' at the top level.

I doubt it's possible to find an overarching strategy to handle all
kinds of errors on the "Gnus" level.  Different errors are, well,
different.

> - There are many ways of logging, and messaging the user. Apart from
>   `message' itself, there's `nnheader-report', `gnus-backend-trace',
>   `nnheader-message(-maybe)', `gnus-message' and its action message log,
>   along with `gnus-final-warning' and `gnus-error'.
>
>   nnheader-report, in particular, seems to often be used as a substitute
>   for actually signaling an error. A server is asked to do something, it
>   fails for some reason and logs the reason with nnheader-report, then
>   returns nil. The caller sees the nil, then retrieves the string with
>   nnheader-get-report, and uses it to signal an error.

Hey!  I invented Go error handling decades before Go was invented!

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-12 16:57   ` Lars-Johan Liman
@ 2021-10-14 17:39     ` Eric Abrahamsen
  2021-10-15 10:48       ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-14 17:39 UTC (permalink / raw)
  To: Lars-Johan Liman; +Cc: Lars Ingebrigtsen, info-gnus-english

[-- Attachment #1: Type: text/plain, Size: 1263 bytes --]

Lars-Johan Liman <liman@liman.se> writes:

> Lol!
>
> Thanks. OK, so I wasn't off the mark, then. :-)
>
> I'm not even sure this needs to be fixed. It's good that the fact that
> the server couldn't be reached is signalled, but continuing seems like
> the right thing to do. The message is somewhat misleading though. How
> about changing the "question" to a "Please ack!" of some kind?

Looking over the code, I'm inclined to agree with Lars-Johan here: there
isn't really any need to halt the process, what's important is that the
user be made aware of the failure. I'm trying to imagine why the user
would _need_ to halt things here. Unless we've got some sort of restart
situation, where the user can eg put in the correct password and try
again, it doesn't seem useful.

Allow me to re-introduce my suggestion of using warnings! It's looking
better and better the more I consider it. `delay-warning' is just what
we want: it puts messages in the hopper, which aren't displayed until
the current command is completely finished, instead of messages
clobbering each other and getting buried. It has its own private buffer,
keeping information separate. There are plenty of user-facing knobs, and
facilities for hiding or silencing the warnings.

See attached!


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gnus-define-errors.diff --]
[-- Type: text/x-patch, Size: 13863 bytes --]

diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 606bd3a39a..3c1387b73f 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -45,6 +45,14 @@ gnus-agent-file-loading-local
 (defvar gnus-agent-file-loading-cache)
 (defvar gnus-topic-alist)
 
+(define-error 'gnus-error "Gnus error")
+(define-error 'gnus-mail-source-error
+  "Gnus mail source error" 'gnus-error)
+(define-error 'gnus-server-error
+  "Gnus server error" 'gnus-error)
+(define-error 'gnus-server-connection-error
+  "Error connecting to server" 'gnus-server-error)
+
 (defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc")
   "Your `.newsrc' file.
 `.newsrc-SERVER' will be used instead if that exists."
@@ -1604,7 +1612,8 @@ gnus-get-unread-articles
 	 (gnus-agent-article-local-times 0)
 	 (archive-method (gnus-server-to-method "archive"))
 	 info group active method cmethod
-	 method-type method-group-list entry)
+	 method-type method-group-list entry
+         failed-methods)
     (gnus-message 6 "Checking new news...")
 
     (while newsrc
@@ -1685,8 +1694,11 @@ gnus-get-unread-articles
 			    gnus-secondary-select-methods))
 	(when (and (not (assoc method type-cache))
 		   (gnus-check-backend-function 'request-list (car method)))
-	  (with-current-buffer nntp-server-buffer
-	    (gnus-read-active-file-1 method nil)))))
+          (condition-case-unless-debug err
+	      (with-current-buffer nntp-server-buffer
+	        (gnus-read-active-file-1 method nil))
+            (gnus-server-connection-error
+             (push (cons method err) failed-methods))))))
 
     ;; Clear out all the early methods.
     (dolist (elem type-cache)
@@ -1697,11 +1709,15 @@ gnus-get-unread-articles
 		    'retrieve-group-data-early (car method))
 		   (not (gnus-method-denied-p method)))
 	  (when (ignore-errors (gnus-get-function method 'open-server))
-	    (unless (gnus-server-opened method)
-	      (gnus-open-server method))
-	    (when (gnus-server-opened method)
-	      ;; Just mark this server as "cleared".
-	      (gnus-retrieve-group-data-early method nil))))))
+            (condition-case-unless-debug err
+	        (progn
+                  (unless (gnus-server-opened method)
+	            (gnus-open-server method))
+	          ;; Just mark this server as "cleared".
+	          (gnus-retrieve-group-data-early method nil))
+              (gnus-server-connection-error
+               (push (cons method err) failed-methods)
+               (setq type-cache (delq elem type-cache))))))))
 
     ;; Start early async retrieval of data.
     (let ((done-methods nil)
@@ -1725,7 +1741,6 @@ gnus-get-unread-articles
 		     ;; be unique at this point, but apparently it
 		     ;; does happen in the wild with some setups.
 		     (not (member sanity-spec done-methods))
-		     (gnus-server-opened method)
 		     (gnus-check-backend-function
 		      'retrieve-group-data-early (car method)))
 		(push sanity-spec done-methods)
@@ -1744,12 +1759,23 @@ gnus-get-unread-articles
 	  (let ((updatep (gnus-check-backend-function
 			  'request-update-info (car method))))
 	    ;; See if any of the groups from this method require updating.
-	    (gnus-read-active-for-groups method infos early-data)
-	    (dolist (info infos)
-	      (inline (gnus-get-unread-articles-in-group
-		       info (gnus-active (gnus-info-group info))
-		       updatep)))))))
-    (gnus-message 6 "Checking new news...done")))
+            (condition-case-unless-debug err
+                (progn
+	          (gnus-read-active-for-groups method infos early-data)
+	          (dolist (info infos)
+	            (inline (gnus-get-unread-articles-in-group
+		             info (gnus-active (gnus-info-group info))
+		             updatep))))
+              ((gnus-server-connection-error gnus-mail-source-error)
+               (push (cons method err) failed-methods)))))))
+    (gnus-message 6 "Checking new news...done")
+    (when failed-methods
+      (let ((warning-series t))
+        (dolist (m failed-methods)
+          (delay-warning
+           '(gnus)
+           (format "Failed to open %s: %S" (car m) (cdr m))
+           :error "*Gnus Warnings*"))))))
 
 (defun gnus-method-rank (type method)
   (cond
diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el
index af0a198376..2515a4261a 100644
--- a/lisp/gnus/mail-source.el
+++ b/lisp/gnus/mail-source.el
@@ -549,13 +549,10 @@ mail-source-fetch
 			   callback mail-source-crash-box))
 	      (mail-source-delete-crash-box))
 	    (+ found
-	       (if (or debug-on-quit debug-on-error)
+	       (condition-case-unless-debug err
 		   (funcall function source callback)
-		 (condition-case err
-		     (funcall function source callback)
-		   (error
-		    (if (and (not mail-source-ignore-errors)
-			     (not
+		 (error
+		  (unless (or mail-source-ignore-errors
 			      (yes-or-no-p
 			       (format "Mail source %s error (%s).  Continue? "
 				       (if (memq ':password source)
@@ -563,10 +560,10 @@ mail-source-fetch
 					     (setcar (cdr (memq ':password s))
 						     "********")
 					     s)
-					 source)
-				       (cadr err)))))
-		      (error "Cannot get new mail"))
-		    0)))))))))
+				         source)
+				       (cadr err))))
+		    (signal 'gnus-mail-source-error (list source err)))
+		  0))))))))
 
 (declare-function gnus-message "gnus-util" (level &rest args))
 
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 8a2acf6459..3305b6edd2 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -456,9 +456,7 @@ nnimap-open-connection
 		   while (eq stream 'no-connect)
 		   finally (return stream))
 	   (nnimap-open-connection-1 buffer))))
-    (if (eq stream 'no-connect)
-	nil
-      stream)))
+    stream))
 
 ;; This is only needed for Windows XP or earlier
 (defun nnimap-map-port (port)
@@ -534,7 +532,8 @@ nnimap-open-connection-1
 	    (progn
 	      (nnheader-report 'nnimap "Unable to contact %s:%s via %s"
 			       nnimap-address (car ports) nnimap-stream)
-	      'no-connect)
+	      (signal 'gnus-server-connection-error
+                      (list nnimap-object)))
 	  (set-process-query-on-exit-flag stream nil)
 	  (if (not (string-match-p "[*.] \\(OK\\|PREAUTH\\)" greeting))
 	      (nnheader-report 'nnimap "%s" greeting)
diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el
index bcf01cfa9e..1a9258273c 100644
--- a/lisp/gnus/nnmail.el
+++ b/lisp/gnus/nnmail.el
@@ -1825,25 +1825,22 @@ nnmail-get-new-mail-1
       ;; and fetch the mail from each.
       (while (setq source (pop fetching-sources))
 	(when (setq new
-		    (condition-case cond
-			(mail-source-fetch
-			 source
-			 (let ((smsym (intern (format "%s-save-mail" method)))
+		    (or (mail-source-fetch
+		         source
+		         (let ((smsym (intern (format "%s-save-mail" method)))
 			       (ansym (intern (format "%s-active-number" method)))
 			       (src source))
-			   (lambda (file orig-file)
+		           (lambda (file orig-file)
 			     (nnmail-split-incoming
 			      file smsym
 			      spool-func
 			      (or in-group
-				  (if (equal file orig-file)
+			          (if (equal file orig-file)
 				      nil
 				    (nnmail-get-split-group orig-file
 							    src)))
 			      ansym))))
-		      ((error quit)
-		       (message "Mail source %s failed: %s" source cond)
-		       0)))
+                        0))
 	  (cl-incf total new)
 	  (cl-incf i)))
       ;; If we did indeed read any incoming spools, we save all info.
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el
index 690761a2d6..8d2b8d4cef 100644
--- a/lisp/gnus/nnmaildir.el
+++ b/lisp/gnus/nnmaildir.el
@@ -670,63 +670,65 @@ nnmaildir-open-server
   (let ((server (alist-get server-string nnmaildir--servers
 			   nil nil #'equal))
 	dir size x)
-    (catch 'return
-      (if server
-	  (and (nnmaildir--srv-groups server)
-	       (setq nnmaildir--cur-server server)
-	       (throw 'return t))
-	(setq server (make-nnmaildir--srv :address server-string))
-	(let ((inhibit-quit t))
-	  (setf (alist-get server-string nnmaildir--servers
-			   nil nil #'equal)
-		server)))
-      (setq dir (assq 'directory defs))
-      (unless dir
-	(setf (nnmaildir--srv-error server)
-	      "You must set \"directory\" in the select method")
-	(throw 'return nil))
-      (setq dir (cadr dir)
-	    dir (eval dir t)	;FIXME: Why `eval'?
-	    dir (expand-file-name dir)
-	    dir (file-name-as-directory dir))
-      (unless (file-exists-p dir)
-	(setf (nnmaildir--srv-error server) (concat "No such directory: " dir))
-	(throw 'return nil))
-      (setf (nnmaildir--srv-dir server) dir)
-      (setq x (assq 'directory-files defs))
-      (if (null x)
-	  (setq x (if nnheader-directory-files-is-safe 'directory-files
-		    'nnheader-directory-files-safe))
-	(setq x (cadr x))
-	(unless (functionp x)
-	  (setf (nnmaildir--srv-error server)
-		(concat "Not a function: " (prin1-to-string x)))
-	  (throw 'return nil)))
-      (setf (nnmaildir--srv-ls server) x)
-      (setq size (length (funcall x dir nil "\\`[^.]" 'nosort)))
-      (and (setq x (assq 'get-new-mail defs))
-	   (setq x (cdr x))
-	   (car x)
-	   (setf (nnmaildir--srv-gnm server) t)
-	   (require 'nnmail))
-      (setq x (assq 'target-prefix defs))
-      (if x
-	  (progn
-	    (setq x (cadr x)
-		  x (eval x t))	;FIXME: Why `eval'?
-	    (setf (nnmaildir--srv-target-prefix server) x))
-	(setq x (assq 'create-directory defs))
-	(if x
-	    (progn
-	      (setq x (cadr x)
-		    x (eval x t) ;FIXME: Why `eval'?
-		    x (file-name-as-directory x))
-	      (setf (nnmaildir--srv-target-prefix server) x))
-	  (setf (nnmaildir--srv-target-prefix server) "")))
-      (setf (nnmaildir--srv-groups server)
-	    (gnus-make-hashtable size))
-      (setq nnmaildir--cur-server server)
-      t)))
+    (unless
+	(catch 'return
+	  (if server
+	      (and (nnmaildir--srv-groups server)
+		   (setq nnmaildir--cur-server server)
+		   (throw 'return t))
+	    (setq server (make-nnmaildir--srv :address server-string))
+	    (let ((inhibit-quit t))
+	      (setf (alist-get server-string nnmaildir--servers
+			       nil nil #'equal)
+		    server)))
+	  (setq dir (assq 'directory defs))
+	  (unless dir
+	    (setf (nnmaildir--srv-error server)
+		  "You must set \"directory\" in the select method")
+	    (throw 'return nil))
+	  (setq dir (cadr dir)
+		dir (eval dir t)	;FIXME: Why `eval'?
+		dir (expand-file-name dir)
+		dir (file-name-as-directory dir))
+	  (unless (file-exists-p dir)
+	    (setf (nnmaildir--srv-error server) (concat "No such directory: " dir))
+	    (throw 'return nil))
+	  (setf (nnmaildir--srv-dir server) dir)
+	  (setq x (assq 'directory-files defs))
+	  (if (null x)
+	      (setq x (if nnheader-directory-files-is-safe 'directory-files
+			'nnheader-directory-files-safe))
+	    (setq x (cadr x))
+	    (unless (functionp x)
+	      (setf (nnmaildir--srv-error server)
+		    (concat "Not a function: " (prin1-to-string x)))
+	      (throw 'return nil)))
+	  (setf (nnmaildir--srv-ls server) x)
+	  (setq size (length (funcall x dir nil "\\`[^.]" 'nosort)))
+	  (and (setq x (assq 'get-new-mail defs))
+	       (setq x (cdr x))
+	       (car x)
+	       (setf (nnmaildir--srv-gnm server) t)
+	       (require 'nnmail))
+	  (setq x (assq 'target-prefix defs))
+	  (if x
+	      (progn
+		(setq x (cadr x)
+		      x (eval x t))	;FIXME: Why `eval'?
+		(setf (nnmaildir--srv-target-prefix server) x))
+	    (setq x (assq 'create-directory defs))
+	    (if x
+		(progn
+		  (setq x (cadr x)
+			x (eval x t)	;FIXME: Why `eval'?
+			x (file-name-as-directory x))
+		  (setf (nnmaildir--srv-target-prefix server) x))
+	      (setf (nnmaildir--srv-target-prefix server) "")))
+	  (setf (nnmaildir--srv-groups server)
+		(gnus-make-hashtable size))
+	  (setq nnmaildir--cur-server server)
+	  t)
+      (signal 'gnus-server-connection-error (list server)))))
 
 (defun nnmaildir--parse-filename (file)
   (let ((prefix (car file))
diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el
index 18acc73aad..98cbe79e8b 100644
--- a/lisp/gnus/nnml.el
+++ b/lisp/gnus/nnml.el
@@ -163,17 +163,18 @@ nnml-open-server
   (nnoo-change-server 'nnml server defs)
   (when (not (file-exists-p nnml-directory))
     (ignore-errors (make-directory nnml-directory t)))
-  (cond
-   ((not (file-exists-p nnml-directory))
-    (nnml-close-server)
-    (nnheader-report 'nnml "Couldn't create directory: %s" nnml-directory))
-   ((not (file-directory-p (file-truename nnml-directory)))
-    (nnml-close-server)
-    (nnheader-report 'nnml "Not a directory: %s" nnml-directory))
-   (t
-    (nnheader-report 'nnml "Opened server %s using directory %s"
-		     server nnml-directory)
-    t)))
+  (let (msg)
+    (if (or (and (not (file-exists-p nnml-directory))
+                 (setq msg "Couldn't create directory: %s"))
+            (and (not (file-directory-p (file-truename nnml-directory)))
+                 (setq msg "Not a directory: %s")))
+        (progn
+          (nnml-close-server)
+          (nnheader-report 'nnml msg nnml-directory)
+          (signal 'gnus-server-connection-error (list server)))
+      (nnheader-report 'nnml "Opened server %s using directory %s"
+		       server nnml-directory)
+      t)))
 
 (deffoo nnml-request-regenerate (server)
   (nnml-possibly-change-directory nil server)
diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el
index 615a3c931b..2f8b271c55 100644
--- a/lisp/gnus/nntp.el
+++ b/lisp/gnus/nntp.el
@@ -1296,7 +1296,8 @@ nntp-open-connection
 	(goto-char (point-min))
 	(nnheader-report 'nntp "Error when connecting: %s"
 			 (buffer-substring (point) (line-end-position))))
-      (setq process nil))
+      (setq process nil)
+      (signal 'gnus-server-connection-error (list nntp-address)))
     (unless process
       (nntp-kill-buffer pbuffer))
     (when (and (buffer-live-p pbuffer)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-14 11:22                     ` Lars Ingebrigtsen
@ 2021-10-14 18:31                       ` Eric Abrahamsen
  2021-10-15 10:42                         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-14 18:31 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: info-gnus-english

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> On second thought you're not wrong here: the various *-open-server
>> deffoos report their own failures with `nnheader-report' instead of
>> signaling errors, and then `gnus-open-server' swallows any other errors
>> and converts them to messages.
>
> Ah.  I knew there was something like that somewhere.  :-)
>
>> Failures arrived at via `gnus-request-scan' mostly show up as actual
>> errors.
>
> Perhaps we should adjust those errors to be nnheader-report thingies
> instead?
>
>> - When the gnus-open-server deffoo processes fail, they (or their
>>   downstream functions) signal 'gnus-server-connection-error. (I didn't
>>   go through and do this for every backend, just enough to get the
>>   idea.)
>> - Mail source fetching can fail, in which case 'gnus-mail-source-error
>>   is signaled. nnmail.el no longer handles this error: it propagates up
>>   and out through gnus-request-scan.
>
> I've just skimmed the patch, but the approach looks sound to me (in
> general).
>
>> Some observations and questions:
>>
>> - There are many places and depth-levels in Gnus where failure modes are
>>   dealt with as messages (in effect working like `with-demoted-errors')
>>   or as nil return values from functions, which are then converted into
>>   messages, or sometimes even re-signaled as an actual `error' with a
>>   new message string. This often ends up burying real errors, and/or
>>   making debug on error hard to use. We could try flattening this out:
>>   low-level functions signal errors, and only top-level functions in
>>   gnus-start/gnus-group/gnus-sum get to catch them at the last minute,
>>   and only if necessary (other layers can of course catch and re-signal
>>   the errors if some cleanup work needs to be done). I have no idea if
>>   this would end up working out, but I think it would be good to try.
>>   And more use of `condition-case-unless-debug' at the top level.
>
> I doubt it's possible to find an overarching strategy to handle all
> kinds of errors on the "Gnus" level.  Different errors are, well,
> different.

Yeah, I'm trying to decide if it's worth introducing this new approach
at all. I'd hate to put in something that ends up only being useful in
49% of cases, and now there's yet another system that future code readers
have to make sense of.

I'm also not sure it solves enough problems. For instance, I recently
committed something to nnimap.el that cleans up `nnimap-process-buffers'
when an IMAP connection dies. That happens in like three or four
different places. Ideally a signal handling approach would let us do
that cleanup in a single spot -- either an actual single spot, or a
macro we only have to write once. Kind of a generalization of
`nntp-with-open-group', except it catches any instance of
'gnus-server-error, rather than requiring an explicitly-thrown symbol. I
don't quite see that this is feasible right now.

ANYWAY... I sent a patch suggestion for the mail-source problem in a
separate message. I'm kind of waffling on the rest of this custom error
stuff.

In the meantime I got a backtrace on my stop-the-world nntp connection
error, which I've posted below. I guess there's nothing mysterious about
it -- the process dies (I can't tell if it's actually the timeout doing
it or not), and nntp-accept-process-output/nntp-report ends up raising
the error, and there's nothing up the line to catch it. Does this look
surprising or wrong for any reason?


  (if nntp--report-1 (progn (if nntp-record-commands (progn (nntp-record-command "*** CONNECTION LOST ***"))) (throw 'nntp-with-open-group-error t)) (if nntp-record-commands (progn (nntp-record-command "*** CALLED nntp-report ***"))) (nnheader-report 'nntp args) (debug) (apply #'error args))
  nntp-report("Server closed connection")
  nntp-accept-process-output(#<process nntpd>)
  nntp-accept-response()
  #f(compiled-function () #<bytecode -0x16437790137177e>)()
  funcall(#f(compiled-function () #<bytecode -0x16437790137177e>))
  (condition-case nil (funcall bodyfun) (quit (if debug-on-quit nil (nntp-close-server)) (signal 'quit nil)))
  (setq nntp-with-open-group-internal (condition-case nil (funcall bodyfun) (quit (if debug-on-quit nil (nntp-close-server)) (signal 'quit nil))))
  (unwind-protect (setq nntp-with-open-group-internal (condition-case nil (funcall bodyfun) (quit (if debug-on-quit nil (nntp-close-server)) (signal 'quit nil)))) (if timer (progn (cancel-timer timer))))
  (let ((timer (and nntp-connection-timeout (run-at-time nntp-connection-timeout nil #'(lambda nil (let* ... ...)))))) (unwind-protect (setq nntp-with-open-group-internal (condition-case nil (funcall bodyfun) (quit (if debug-on-quit nil (nntp-close-server)) (signal 'quit nil)))) (if timer (progn (cancel-timer timer)))) nil)
  (catch 'nntp-with-open-group-error (nntp-possibly-change-group group server connectionless) (let ((timer (and nntp-connection-timeout (run-at-time nntp-connection-timeout nil #'(lambda nil ...))))) (unwind-protect (setq nntp-with-open-group-internal (condition-case nil (funcall bodyfun) (quit (if debug-on-quit nil (nntp-close-server)) (signal 'quit nil)))) (if timer (progn (cancel-timer timer)))) nil))
  (while (catch 'nntp-with-open-group-error (nntp-possibly-change-group group server connectionless) (let ((timer (and nntp-connection-timeout (run-at-time nntp-connection-timeout nil #'...)))) (unwind-protect (setq nntp-with-open-group-internal (condition-case nil (funcall bodyfun) (quit (if debug-on-quit nil ...) (signal ... nil)))) (if timer (progn (cancel-timer timer)))) nil)) (setq nntp--report-1 nntp-report-n))
  (let ((nntp-report-n nntp--report-1) (nntp--report-1 t) (nntp-with-open-group-internal nil)) (while (catch 'nntp-with-open-group-error (nntp-possibly-change-group group server connectionless) (let ((timer (and nntp-connection-timeout (run-at-time nntp-connection-timeout nil ...)))) (unwind-protect (setq nntp-with-open-group-internal (condition-case nil (funcall bodyfun) (quit ... ...))) (if timer (progn (cancel-timer timer)))) nil)) (setq nntp--report-1 nntp-report-n)) nntp-with-open-group-internal)
  nntp-with-open-group-function(nil "news.gmane.io" nil #f(compiled-function () #<bytecode -0x16437790137177e>))
  nntp-finish-retrieve-group-infos("news.gmane.io" ... 7)
  gnus-finish-retrieve-group-infos((nntp "news.gmane.io") ... 7)
  gnus-read-active-for-groups((nntp "news.gmane.io") ... 7)


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-14 18:31                       ` Eric Abrahamsen
@ 2021-10-15 10:42                         ` Lars Ingebrigtsen
  2021-10-15 17:43                           ` Eric Abrahamsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-15 10:42 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: info-gnus-english

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> In the meantime I got a backtrace on my stop-the-world nntp connection
> error, which I've posted below. I guess there's nothing mysterious about
> it -- the process dies (I can't tell if it's actually the timeout doing
> it or not), and nntp-accept-process-output/nntp-report ends up raising
> the error, and there's nothing up the line to catch it. Does this look
> surprising or wrong for any reason?
>
>   (if nntp--report-1 (progn (if nntp-record-commands (progn
> (nntp-record-command "*** CONNECTION LOST ***"))) (throw

Network errors are common, so it shouldn't be throwing an error in the
first place.

But I can't recall ever seeing the `nntp-report' function before, so who
knows what the logic is.  :-/  That looks like a...  debugging function?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-14 17:39     ` Eric Abrahamsen
@ 2021-10-15 10:48       ` Lars Ingebrigtsen
  2021-10-15 17:52         ` Eric Abrahamsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-15 10:48 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: Lars-Johan Liman, info-gnus-english

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> Looking over the code, I'm inclined to agree with Lars-Johan here: there
> isn't really any need to halt the process, what's important is that the
> user be made aware of the failure.

I agree.

> Allow me to re-introduce my suggestion of using warnings! It's looking
> better and better the more I consider it. `delay-warning' is just what
> we want: it puts messages in the hopper, which aren't displayed until
> the current command is completely finished, instead of messages
> clobbering each other and getting buried. It has its own private buffer,
> keeping information separate. There are plenty of user-facing knobs, and
> facilities for hiding or silencing the warnings.

I'm not sure I want to be popping up a buffer at the user for network
errors and the like -- it's expected that a news reader will have some
network problems, and putting up a buffer about it isn't very helpful.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-15 10:42                         ` Lars Ingebrigtsen
@ 2021-10-15 17:43                           ` Eric Abrahamsen
  0 siblings, 0 replies; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-15 17:43 UTC (permalink / raw)
  To: info-gnus-english

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> In the meantime I got a backtrace on my stop-the-world nntp connection
>> error, which I've posted below. I guess there's nothing mysterious about
>> it -- the process dies (I can't tell if it's actually the timeout doing
>> it or not), and nntp-accept-process-output/nntp-report ends up raising
>> the error, and there's nothing up the line to catch it. Does this look
>> surprising or wrong for any reason?
>>
>>   (if nntp--report-1 (progn (if nntp-record-commands (progn
>> (nntp-record-command "*** CONNECTION LOST ***"))) (throw
>
> Network errors are common, so it shouldn't be throwing an error in the
> first place.
>
> But I can't recall ever seeing the `nntp-report' function before, so who
> knows what the logic is.  :-/  That looks like a...  debugging function?

The function has existed and raised an error since the "dawn of time"
(since CVS days), I guess I'm surprised this hasn't annoyed anyone else.
Basically it shadows `nnheader-report', and gives the server a single
chance to reconnect in case of failure -- the "nntp-with-open-group"
mechanism -- before failing altogether. All that's fine, I wish nnimap
had something similar, but raising the error seems wrong.

In fact raising the error would be the right thing in the code sketch I
posted above! This code is ahead of its time.

Anyway, simply removing the call to error should do the trick. That
will leave `nnheader-report' as the final form, which returns nil.
`nntp-report' is the final form everywhere it's called, so the nil goes
up to callers, which will (mostly) interpret that as failure.

Eric



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-15 10:48       ` Lars Ingebrigtsen
@ 2021-10-15 17:52         ` Eric Abrahamsen
  2021-10-18  6:42           ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-15 17:52 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Lars-Johan Liman, info-gnus-english

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> Looking over the code, I'm inclined to agree with Lars-Johan here: there
>> isn't really any need to halt the process, what's important is that the
>> user be made aware of the failure.
>
> I agree.
>
>> Allow me to re-introduce my suggestion of using warnings! It's looking
>> better and better the more I consider it. `delay-warning' is just what
>> we want: it puts messages in the hopper, which aren't displayed until
>> the current command is completely finished, instead of messages
>> clobbering each other and getting buried. It has its own private buffer,
>> keeping information separate. There are plenty of user-facing knobs, and
>> facilities for hiding or silencing the warnings.
>
> I'm not sure I want to be popping up a buffer at the user for network
> errors and the like -- it's expected that a news reader will have some
> network problems, and putting up a buffer about it isn't very helpful.

The pop-up part of it is very easy to fix, it could even be added to
the Gnus window configuration stuff so people can have the
warnings/reports visible in *Group* but not elsewhere, etc.

The real advantages are 1) the warnings go into their own buffer, so
they don't get lost in *Messages*, and 2) they can be displayed after
the current command returns. Right now, the message about mail source
failure message will never be seen by the user.

We could easily emulate that behavior, it's just that warnings give it
to us for free.

There are other approaches, as well. I could also do a limited version
of the custom error approach, only for mail sources.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-15 17:52         ` Eric Abrahamsen
@ 2021-10-18  6:42           ` Lars Ingebrigtsen
  2021-10-18 15:03             ` Eric Abrahamsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-18  6:42 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: Lars-Johan Liman, info-gnus-english

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> The pop-up part of it is very easy to fix, it could even be added to
> the Gnus window configuration stuff so people can have the
> warnings/reports visible in *Group* but not elsewhere, etc.

Perhaps it could be an opt-in thing.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-18  6:42           ` Lars Ingebrigtsen
@ 2021-10-18 15:03             ` Eric Abrahamsen
  2021-10-19 13:42               ` Lars Ingebrigtsen
  0 siblings, 1 reply; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-18 15:03 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Lars-Johan Liman, info-gnus-english

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> The pop-up part of it is very easy to fix, it could even be added to
>> the Gnus window configuration stuff so people can have the
>> warnings/reports visible in *Group* but not elsewhere, etc.
>
> Perhaps it could be an opt-in thing.

I'll work something up. `nnheader-report' is fine specifically for
backend-related errors, but it seems like this could fill a nice gap for
"other errors" that aren't necessarily related to a particular backend.

In the meantime, what do you think about removing the call to `error' at
the end of `nntp-report'?


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-18 15:03             ` Eric Abrahamsen
@ 2021-10-19 13:42               ` Lars Ingebrigtsen
  2021-10-19 15:15                 ` Eric Abrahamsen
  0 siblings, 1 reply; 23+ messages in thread
From: Lars Ingebrigtsen @ 2021-10-19 13:42 UTC (permalink / raw)
  To: Eric Abrahamsen; +Cc: Lars-Johan Liman, info-gnus-english

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> In the meantime, what do you think about removing the call to `error' at
> the end of `nntp-report'?

I'm not sure what the repercussions would be, but it sounds like it
should be possible.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Mail source unreachable - continue yes/no?
  2021-10-19 13:42               ` Lars Ingebrigtsen
@ 2021-10-19 15:15                 ` Eric Abrahamsen
  0 siblings, 0 replies; 23+ messages in thread
From: Eric Abrahamsen @ 2021-10-19 15:15 UTC (permalink / raw)
  To: info-gnus-english

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> In the meantime, what do you think about removing the call to `error' at
>> the end of `nntp-report'?
>
> I'm not sure what the repercussions would be, but it sounds like it
> should be possible.

I'm running it now, and will push in a couple days if it looks okay.



^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2021-10-19 15:39 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-11  6:07 Mail source unreachable - continue yes/no? Lars-Johan Liman
2021-10-12 12:39 ` Lars Ingebrigtsen
2021-10-12 16:50   ` Eric Abrahamsen
2021-10-12 16:57     ` Lars Ingebrigtsen
2021-10-12 17:49       ` Eric Abrahamsen
2021-10-12 17:56         ` Lars Ingebrigtsen
2021-10-12 18:18           ` Eric Abrahamsen
2021-10-12 18:25             ` Lars Ingebrigtsen
2021-10-12 19:50               ` Eric Abrahamsen
2021-10-13 11:33                 ` Lars Ingebrigtsen
2021-10-14  5:03                   ` Eric Abrahamsen
2021-10-14 11:22                     ` Lars Ingebrigtsen
2021-10-14 18:31                       ` Eric Abrahamsen
2021-10-15 10:42                         ` Lars Ingebrigtsen
2021-10-15 17:43                           ` Eric Abrahamsen
2021-10-12 16:57   ` Lars-Johan Liman
2021-10-14 17:39     ` Eric Abrahamsen
2021-10-15 10:48       ` Lars Ingebrigtsen
2021-10-15 17:52         ` Eric Abrahamsen
2021-10-18  6:42           ` Lars Ingebrigtsen
2021-10-18 15:03             ` Eric Abrahamsen
2021-10-19 13:42               ` Lars Ingebrigtsen
2021-10-19 15:15                 ` Eric Abrahamsen

Announcements and discussions for Gnus, the GNU Emacs Usenet newsreader

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.vuxu.org/info-gnus-english

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 info-gnus-english info-gnus-english/ https://inbox.vuxu.org/info-gnus-english \
		info-gnus-english@inbox.vuxu.org
	public-inbox-index info-gnus-english

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.emacs.gnus.user


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git