From 59b9b74fc3e6d4989d48fda96fea775d33a43d56 Mon Sep 17 00:00:00 2001
From: Marcel de Rooy
Date: Mon, 13 Apr 2026 11:01:23 +0200
Subject: [PATCH] Bug 42321: Improve handling of empty Z3950/SRU search results
Skips the empty results; only reports the 'real failures'.
Includes adding a grand total of hits to the form.
Some preliminary work to remove the hardcoded 20 results per target
in the code.
This is not yet a complete solution, but an improvement. The code in
C4/Breeding needs a larger overhaul. (And there might be an issue on
the Folio server side at LOC.)
Test plan:
Without this patch:
Use the LOC SRU server (since if frequently generates errcode 61).
Try the same search several times in a row (with Go). You probably will
come across the "LOC SRU record x: 0" messages. (Random behavior.)
Apply this patch.
Repeat the above. Notice that you will sometimes see the error 61 (and the
tip to refresh) but not the code 0 messages.
Run t/db../Breeding.t
Signed-off-by: Marcel de Rooy
Signed-off-by: David Nind
Signed-off-by: Lisette Scheer
Signed-off-by: Lucas Gass
---
C4/Breeding.pm | 32 ++++++++++++-------
.../en/modules/cataloguing/z3950_search.tt | 14 +++++---
2 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/C4/Breeding.pm b/C4/Breeding.pm
index bdabd8828a..a3595acac9 100644
--- a/C4/Breeding.pm
+++ b/C4/Breeding.pm
@@ -155,7 +155,9 @@ sub Z3950Search {
}
my $xslh = Koha::XSLT::Base->new;
- my $nremaining = $s;
+ my $nremaining = $s;
+ my $hits_per_page = 20; #TODO make configurable
+ my $total_hits = 0;
while ( $nremaining-- ) {
my $k;
my $event;
@@ -169,18 +171,22 @@ sub Z3950Search {
my ($error) = $oConnection[$k]->error_x(); #ignores errmsg, addinfo, diagset
if ($error) {
if ( $error =~ m/^(10000|10007)$/ ) {
- push( @errconn, { server => $servers[$k]->{host}, error => $error } );
+ push( @errconn, { server => $servers[$k]->{host}, errcode => $error } );
}
} else {
my $numresults = $oResult[$k]->size();
+ $total_hits += $numresults;
my $i;
my $res;
- if ( $numresults > 0 and $numresults >= ( ( $page - 1 ) * 20 ) ) {
- $show_next = 1 if $numresults >= ( $page * 20 );
- $total_pages = int( $numresults / 20 ) + 1 if $total_pages < ( $numresults / 20 );
+ if ( $numresults > 0 and $numresults >= ( ( $page - 1 ) * $hits_per_page ) ) {
+ $show_next = 1 if $numresults >= ( $page * $hits_per_page );
+ $total_pages = int( $numresults / $hits_per_page ) + 1
+ if $total_pages < ( $numresults / $hits_per_page );
for (
- $i = ( $page - 1 ) * 20 ;
- $i < ( ( $numresults < ( $page * 20 ) ) ? $numresults : ( $page * 20 ) ) ;
+ $i = ( $page - 1 ) * $hits_per_page ;
+ $i < (
+ ( $numresults < ( $page * $hits_per_page ) ) ? $numresults : ( $page * $hits_per_page )
+ ) ;
$i++
)
{
@@ -191,14 +197,17 @@ sub Z3950Search {
$xslh
); #ignores error in sequence numbering
push @breeding_loop, $res if $res;
- push @errconn, { server => $servers[$k]->{servername}, error => $error, seq => $i + 1 }
+ push @errconn, { server => $servers[$k]->{servername}, errcode => $error, seq => $i + 1 }
if $error;
} else {
+ my @diags = $oConnection[$k]->error_x(); # errcode, errmsg, addinfo, diagset
+ next unless $diags[0]; # Just silently ignore empty results
push @errconn,
{
- 'server' => $servers[$k]->{servername},
- error => ( ( $oConnection[$k]->error_x() )[0] ),
- error_msg => ( ( $oConnection[$k]->error_x() )[1] ), seq => $i + 1
+ server => $servers[$k]->{servername},
+ errcode => $diags[0],
+ errmsg => $diags[1],
+ seq => $i + 1,
};
}
}
@@ -212,6 +221,7 @@ sub Z3950Search {
total_pages => $total_pages,
show_nextbutton => $show_next ? 1 : 0,
show_prevbutton => $page != 1,
+ total_hits => $total_hits,
);
} # while nremaining
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt
index 5793d39178..2ff8c7aa21 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/z3950_search.tt
@@ -103,19 +103,23 @@
[% IF ( dewey ) %]Dewey: [% dewey | html %][% END %]
[% IF ( srchany ) %]Raw (any): [% srchany | html %][% END %]
[% IF ( stdid ) %]Standard ID: [% stdid | html %][% END %]
+ (Having [% total_hits | html %] results)
[% IF ( errconn ) %]
[% FOREACH errcon IN errconn %]
- [% IF ( errcon.error == '10000' ) %]
+ [% IF ( errcon.errcode == '10000' ) %]
- Connection failed to [% errcon.server | html %]
- [% ELSIF ( errcon.error == '10007' ) %]
+ [% ELSIF ( errcon.errcode == '10007' ) %]
- Connection timeout to [% errcon.server | html %]
- [% ELSIF errcon.error.match( '^XSLTH' ) %]
- - [% errcon.server | html %] record [% errcon.seq | html %]: [% PROCESS 'xslt-handler.inc' code=errcon.error %]
+ [% ELSIF errcon.errcode.match( '^XSLTH' ) %]
+ - [% errcon.server | html %] record [% errcon.seq | html %]: [% PROCESS 'xslt-handler.inc' code=errcon.errcode %]
[% ELSE %]
- - [% errcon.error_msg | html %] (ref. [% errcon.error | html %]) for [% errcon.server | html %] result [% errcon.seq | html %]
+ -
+ [% errcon.errmsg | html %] (ref. [% errcon.errcode | html %]) for [% errcon.server | html %] result [% errcon.seq | html %]
+ [% IF errcon.errcode == '61' # 'First record position out of range' %](TIP: Refresh with Go button.)[% END %]
+
[% END %]
[% END %]