From 7eaadcc01df782b2ea49f48d403cdd29d191e472 Mon Sep 17 00:00:00 2001 From: MatusBeke Date: Mon, 13 Jul 2026 13:38:31 +0000 Subject: [PATCH] fix(mediafilter): log unparsable-PDF filter-media errors as WARN, not ERROR A corrupt/malformed PDF makes PDFBoxThumbnail and TikaTextExtractionFilter throw a parse IOException that MediaFilterServiceImpl re-logs at ERROR, flooding the nightly filter-media job (~4,655 lines/night) and tripping log-based alerting, even though the job already skips the file and continues. Catch the IOException in both filters, log at WARN and return null so the bitstream is skipped cleanly. (cherry picked from commit 7035a4c417a22cdd3d426ea5e73158fb2583ebeb) Co-authored-by: Claude Opus 4.8 (1M context) Co-Authored-By: Claude Fable 5 --- .../org/dspace/app/mediafilter/PDFBoxThumbnail.java | 8 ++++++++ .../app/mediafilter/TikaTextExtractionFilter.java | 11 +++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/PDFBoxThumbnail.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/PDFBoxThumbnail.java index 94c463b2808..e165a1fc9b0 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/PDFBoxThumbnail.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/PDFBoxThumbnail.java @@ -8,6 +8,7 @@ package org.dspace.app.mediafilter; import java.awt.image.BufferedImage; +import java.io.IOException; import java.io.InputStream; import org.apache.logging.log4j.Logger; @@ -79,6 +80,13 @@ public InputStream getDestinationStream(Item currentItem, InputStream source, bo } catch (InvalidPasswordException ex) { log.error("PDF is encrypted. Cannot create thumbnail (item: {})", currentItem::getHandle); return null; + } catch (IOException ex) { + // A malformed/non-standard PDF (bad %PDF- header, missing xref, truncated file, etc.) + // is a data-quality issue in the source bitstream, not a DSpace fault. Skip the + // thumbnail instead of failing the whole filter-media run. + log.warn("PDF could not be parsed by PDFBox. Cannot create thumbnail (item: {}): {}", + currentItem::getHandle, ex::getMessage); + return null; } // Generate thumbnail derivative and return as IO stream. diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java index 5728f4f42f4..97111952baa 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java @@ -85,10 +85,13 @@ public InputStream getDestinationStream(Item currentItem, InputStream source, bo tika.setMaxStringLength(maxChars); // Tell Tika the maximum number of characters to extract extractedText = tika.parseToString(source); } catch (IOException e) { - System.err.format("Unable to extract text from bitstream in Item %s%n", currentItem.getID().toString()); - e.printStackTrace(System.err); - log.error("Unable to extract text from bitstream in Item {}", currentItem.getID().toString(), e); - throw e; + // A malformed/non-standard source file (e.g. a PDF with a corrupt header, missing + // xref, or truncated content) is a data-quality issue in the bitstream, not a + // DSpace fault. Skip text extraction for it instead of failing the whole + // filter-media run. + log.warn("Unable to extract text from bitstream in Item {}: {}", + currentItem.getHandle(), e.getMessage()); + return null; } catch (OutOfMemoryError oe) { System.err.format("OutOfMemoryError occurred when extracting text from bitstream in Item %s. " + "You may wish to enable 'textextractor.use-temp-file'.%n", currentItem.getID().toString());