about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-11-09 10:09:43 +0000
committerEric Wong <e@80x24.org>2023-11-09 21:53:53 +0000
commitd974977afda1b887313e0143dfa740604b2fc740 (patch)
treeea138e290251d2293c13d5e40ff1c812f3896064 /lib/PublicInbox
parentb35530ccb929a693c4c78b02187a564a7ab5e903 (diff)
downloadpublic-inbox-d974977afda1b887313e0143dfa740604b2fc740.tar.gz
This matches the behavior we have for multi-message mbox files
since we rely on ->close to detect errors on bad mboxes.  This
ensures we'll notice errors reading single messages from stdin.

We'll also start relying more on strace error injection to test
error handling.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/LeiInput.pm13
-rw-r--r--lib/PublicInbox/TestCommon.pm23
2 files changed, 29 insertions, 7 deletions
diff --git a/lib/PublicInbox/LeiInput.pm b/lib/PublicInbox/LeiInput.pm
index 4cd18c09..adb356c9 100644
--- a/lib/PublicInbox/LeiInput.pm
+++ b/lib/PublicInbox/LeiInput.pm
@@ -81,9 +81,11 @@ sub input_fh {
         my ($self, $ifmt, $fh, $name, @args) = @_;
         if ($ifmt eq 'eml') {
                 my $buf = do { local $/; <$fh> };
-                (defined($buf) && eof($fh) && close($fh)) or
-                        return $self->{lei}->child_error(0, <<"");
-error reading $name: $!
+                my $ok = defined($buf) ? 1 : 0;
+                ++$ok if eof($fh);
+                ++$ok if $fh->close;
+                $ok == 3 or return $self->{lei}->child_error($?, <<"");
+error reading $name: $! (\$?=$?)
 
                 PublicInbox::Eml::strip_from($buf);
 
@@ -246,9 +248,8 @@ sub input_path_url {
                         my $rdr = { 2 => $lei->{2} };
                         my $fh = popen_rd($fp, undef, $rdr);
                         eval { $self->input_fh('eml', $fh, $input, @args) };
-                        my @err = ($@ ? $@ : ());
-                        $fh->close or push @err, "\$?=$?";
-                        $lei->child_error($?, "@$fp failed: @err") if @err;
+                        my $err = $@ ? ": $@" : '';
+                        $lei->child_error($?, "@$fp failed$err") if $err || $?;
                 } else {
                         $self->folder_missing("$ifmt:$input");
                 }
diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm
index 83e99b42..46e6a538 100644
--- a/lib/PublicInbox/TestCommon.pm
+++ b/lib/PublicInbox/TestCommon.pm
@@ -28,7 +28,8 @@ BEGIN {
                 quit_waiter_pipe wait_for_eof
                 tcp_host_port test_lei lei lei_ok $lei_out $lei_err $lei_opt
                 test_httpd xbail require_cmd is_xdeeply tail_f
-                ignore_inline_c_missing no_pollerfd no_coredump cfg_new);
+                ignore_inline_c_missing no_pollerfd no_coredump cfg_new
+                strace strace_inject);
         require Test::More;
         my @methods = grep(!/\W/, @Test::More::EXPORT);
         eval(join('', map { "*$_=\\&Test::More::$_;" } @methods));
@@ -933,6 +934,26 @@ sub cfg_new ($;@) {
         PublicInbox::Config->new($f);
 }
 
+our $strace_cmd;
+sub strace () {
+        skip 'linux only test' if $^O ne 'linux';
+        require_cmd('strace', 1);
+}
+
+sub strace_inject () {
+        my $cmd = strace;
+        state $ver = do {
+                require PublicInbox::Spawn;
+                my $v = PublicInbox::Spawn::run_qx([$cmd, '--version']);
+                $v =~ m!version\s+([1-9]+\.[0-9]+)! or
+                                xbail "no strace --version: $v";
+                eval("v$1");
+        };
+        $ver ge v4.16 or skip "$cmd too old for syscall injection (".
+                                sprintf('v%vd', $ver). ' < v4.16)';
+        $cmd
+}
+
 package PublicInbox::TestCommon::InboxWakeup;
 use strict;
 sub on_inbox_unlock { ${$_[0]}->($_[1]) }