From a2584a71f4e40bd15aed721d18efa614440ff47b Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Fri, 3 Apr 2026 19:41:05 +0000 Subject: [PATCH] Bug 42156: Attempt to repair corrupted records and skip when not possible When matching authorities we can die on a bad record, we should add protection against this on top of bug 41843 To test: 1 - Apply index patch and rebuild elastic perl misc/search_tools/rebuild_elasticsearch.pl -r -v 2 - Make a new record matching rule threshold: 1000 type: authority index: authid score: 1000 tag: 001 3 - Choose an authority record and corrupt it: sudo koha-mysql kohadev UPDATE auth_header SET marcxml = UpdateXML(marcxml, '//datafield[@tag="040"]/subfield[@code="c"]',CONCAT('OSt')) WHERE auth_header.authid=92; 4 - View and save the record as marcxml http://localhost:8081/cgi-bin/koha/authorities/detail.pl?authid=92 5 - Cataloging - stage marc records - authority/marcxml/no matching 6 - Confirm it stages 7 - Attempt to match using your new rule 8 - Get an error parsing the marc 9 - Apply patch, restart all 10 - Relaod the staged batch 11 - Attempt matching agaion 12 - Success! Signed-off-by: David Nind Signed-off-by: Martin Renvoize Signed-off-by: Lucas Gass (cherry picked from commit c5adbe081850670a62af6f2bff97abedc07c5b41) Signed-off-by: Jacob O'Mara --- C4/Matcher.pm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/C4/Matcher.pm b/C4/Matcher.pm index 0aaaf818d9..35ba08af79 100644 --- a/C4/Matcher.pm +++ b/C4/Matcher.pm @@ -752,8 +752,16 @@ sub get_matches { my ( $authresults, $total ) = $searcher->search_auth_compat( $search_query, 0, 20 ); foreach my $result (@$authresults) { - my $id = $result->{authid}; - my $target_record = Koha::Authorities->find($id)->record; + my $id = $result->{authid}; + my $target_auth = Koha::Authorities->find($id); + my $target_record = eval { $target_auth->record }; + my $invalid_record = $@ || !$target_record; + if ($invalid_record) { + warn + "Error parsing matched authority record $id, attempting to clean record, record will be skipped if it fails"; + $target_record = $target_auth->record_strip_nonxml; + } + next unless $target_record; $matches->{$id}->{score} += $matchpoint->{'score'}; $matches->{$id}->{record} = $target_record; }