]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
xap_helper: mset: ignore non-ultimate exceptions
authorEric Wong <e@80x24.org>
Thu, 29 May 2025 00:20:30 +0000 (00:20 +0000)
committerEric Wong <e@80x24.org>
Sun, 1 Jun 2025 10:15:49 +0000 (10:15 +0000)
For requests consisting of multiple queries, ignore Xapian
exceptions for all but the last query.  When sending multiple
queries to the `mset' xap_helper command, we only care about the
result of the first successful query where success is defined as
a non-empty mset response.  Thus an exception is considered an
empty mset and we can try other queries from the same request.

lib/PublicInbox/XapHelper.pm
lib/PublicInbox/xh_mset.h
t/xap_helper.t

index a36acf469d873d881962e43b53ab60097cdb56a9..48203de39fecfd2ab669ce356ffe0f73e83be118 100644 (file)
@@ -176,12 +176,15 @@ sub cmd_mset { # to be used by WWW + IMAP
        my @uid_range = @$req{qw(u U)};
        $opt->{uid_range} = \@uid_range if grep(defined, @uid_range) == 2;
        $opt->{threadid} = $req->{T} if defined $req->{T};
-       my $mset = $req->{srch}->mset($qry_str, $opt);
-       my $size = $mset->size;
-       while ($size == 0 && @rest) {
-               $mset = $req->{srch}->mset(shift @rest, $opt);
-               $size = $mset->size;
-       }
+       my ($mset, $size);
+       do {
+               eval {
+                       $mset = $req->{srch}->mset($qry_str, $opt);
+                       $size = $mset->size;
+               };
+               # swallow exceptions for all but the last query
+               die if $@ && !@rest;
+       } while (!$size && (defined($qry_str = shift @rest)));
        say { $req->{0} } 'mset.size=', $size,
                ' .get_matches_estimated=', $mset->get_matches_estimated;
        for my $it ($mset->items) {
index 7d0100932faae0c03a5fcd916f69870ae120df15..8591bbf4f418842b0202ac8422a66b5b4a6746fe 100644 (file)
 static bool cmd_mset(struct req *req)
 {
        if (optind >= req->argc) ABORT("usage: mset [OPTIONS] WANT QRY_STR");
-       const char *qry_str = req->argv[optind];
        CLEANUP_FBUF struct fbuf wbuf = {};
-       Xapian::MSet mset = req->code_search ? commit_mset(req, qry_str) :
+       unsigned long long size = 0;
+       Xapian::MSet mset;
+       do {
+               try {
+                       const char *qry_str = req->argv[optind++];
+                       mset = req->code_search ? commit_mset(req, qry_str) :
                                                mail_mset(req, qry_str);
-       unsigned long long size = mset.size();
-       while (size == 0 && ++optind < req->argc) {
-               qry_str = req->argv[optind];
-               mset = req->code_search ? commit_mset(req, qry_str) :
-                                       mail_mset(req, qry_str);
-               size = mset.size();
-       }
+                       size = mset.size();
+               } catch (const Xapian::Error & e) {
+                       // swallow exceptions for all but the last query
+                       if (optind >= req->argc)
+                               throw;
+               }
+       } while (size == 0 && optind < req->argc);
+
        fbuf_init(&wbuf);
        fprintf(wbuf.fp, "mset.size=%llu .get_matches_estimated=%llu\n",
                size, (unsigned long long)mset.get_matches_estimated());
index 41520866f364e3ae070a1484710d0d5deaffe937..86b44dd24af8fdf2e69ae0f3215e29237eedc7fd 100644 (file)
@@ -249,8 +249,11 @@ for my $n (@NO_CXX) {
 
        # ensure we can try multiple queries and return the first one
        # with >0 matches
-       for my $try ([[], []], [['thisbetternotmatchanything'], ['z:0..']]) {
+       for my $try ([[], []], [['thisbetternotmatchanything'], ['z:0..']],
+                       [['bogus...range ignored'], []],
+                       [['z:0.. dfn:Search.pm'], ['bogus...range never tried']]) {
                pipe $r, $w;
+               diag explain($try);
                $xhc->mkreq([$w], qw(mset), @ibx_shard_args, @{$try->[0]},
                                        'dfn:lib/PublicInbox/Search.pm',
                                        @{$try->[1]});
@@ -286,6 +289,17 @@ for my $n (@NO_CXX) {
                like $rank, qr/\A\d+\z/, 'rank is a digit';
                is scalar(@rest), 0, 'no extra rows returned';
        }
+
+       pipe $r, $w;
+       pipe $err_r, $err_w;
+       $xhc->mkreq([$w, $err_w], qw(mset), @ibx_shard_args, 'bogus...range');
+       close $w;
+       close $err_w;
+       chomp(@res = readline($r));
+       is_deeply \@res, [], 'no output on bogus query';
+       chomp(@res = readline($err_r));
+       ok scalar(@res) && $res[0], 'got error on bogus query';
+
        my $nr;
        for my $i (7, 8, 39, 40) {
                pipe($err_r, $err_w);