]> Sergey Matveev's repositories - public-inbox.git/commitdiff
lei: bail out earlier on IMAP writer failures
authorEric Wong <e@80x24.org>
Sat, 10 Sep 2022 01:18:59 +0000 (01:18 +0000)
committerEric Wong <e@80x24.org>
Sat, 10 Sep 2022 01:35:02 +0000 (01:35 +0000)
Excessive IMAP connections can overload IMAP servers and cause
clients to be disconnected without diagnostic messages.
Use $lei->fail on these exceptions to propagate errors to the
CLI ASAP to avoid further errors down the line.

This ought to make problems more apparent for users using IMAP
destinations.

Reported-by: Ricardo Ribalda <ribalda@chromium.org>
Link: https://public-inbox.org/meta/CANiDSCsDfutAUMBLPZbxdyka+_jnhv+4YNYdL9QPRoC=wNUGCQ@mail.gmail.com/
lib/PublicInbox/LeiToMail.pm
lib/PublicInbox/NetReader.pm

index 2aa3977e8034d01f744c05a3a7c5598c9e97890e..03cbde3bd7cf264c141f885a8b4e73c157b30865 100644 (file)
@@ -310,8 +310,11 @@ sub _imap_write_cb ($$) {
        my $dedupe = $lei->{dedupe};
        $dedupe->prepare_dedupe if $dedupe;
        my $append = $lei->{net}->can('imap_append');
-       my $uri = $self->{uri};
-       my $mic = $lei->{net}->mic_get($uri);
+       my $uri = $self->{uri} // die 'BUG: no {uri}';
+       my $mic = $lei->{net}->mic_get($uri) // die <<EOM;
+E: $uri connection failed.
+E: Consider using `--jobs ,1' to limit IMAP connections
+EOM
        my $folder = $uri->mailbox;
        $uri->uidvalidity($mic->uidvalidity($folder));
        my $lse = $lei->{lse}; # may be undef
@@ -749,7 +752,8 @@ sub do_post_auth {
                $au_peers->[1] = undef;
                sysread($au_peers->[0], my $barrier1, 1);
        }
-       $self->{wcb} = $self->write_cb($lei);
+       eval { $self->{wcb} = $self->write_cb($lei) };
+       $lei->fail($@) if $@;
        if ($au_peers) { # wait for peer l2m to set write_cb
                $au_peers->[3] = undef;
                sysread($au_peers->[2], my $barrier2, 1);
index c1af03a3f8b972db9a8ff38f0b081652dbb90a53..4de2583e00ddeb307aea560da2b9070e3dadf99c 100644 (file)
@@ -685,7 +685,13 @@ sub mic_get {
        }
        my $mic = mic_new($self, $mic_arg, $sec, $uri);
        $cached //= {}; # invalid placeholder if no cache enabled
-       $mic && $mic->IsConnected ? ($cached->{$sec} = $mic) : undef;
+       if ($mic && $mic->IsConnected) {
+               $cached->{$sec} = $mic;
+       } else {
+               warn 'IMAP LastError: ',$mic->LastError, "\n" if $mic;
+               warn "IMAP errno: $!\n" if $!;
+               undef;
+       }
 }
 
 sub imap_each {