diff --git a/CHANGELOG.md b/CHANGELOG.md index c62972b..1d286cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. The format ### Fixed - Initialize PDFium's form environment in `get_page_image` so that filled AcroForm field content is included when rendering pages via `Page.to_image()`. ([#1367](https://github.com/jsvine/pdfplumber/issues/1367)) +- Include the wrapped exception's class name in `PdfminerException`'s message when `pdfminer.six` raises an exception without one (e.g. `PDFPasswordIncorrect`), which previously surfaced as a blank error message. ## [0.11.10] — 2026-06-14 diff --git a/README.md b/README.md index 59668e7..42b0789 100644 --- a/README.md +++ b/README.md @@ -576,6 +576,7 @@ Many thanks to the following users who've contributed ideas, features, and fixes - [Anton Ilin](https://github.com/bronislav) - [Sebastian Cao](https://github.com/cycsmail) - [Kaspar Naraghi](https://github.com/kaninaba94) +- [Siddharth Gaur](https://github.com/siddharthgaur1) ## Contributing diff --git a/pdfplumber/utils/exceptions.py b/pdfplumber/utils/exceptions.py index f96cc03..b8773a7 100644 --- a/pdfplumber/utils/exceptions.py +++ b/pdfplumber/utils/exceptions.py @@ -3,4 +3,11 @@ class MalformedPDFException(Exception): class PdfminerException(Exception): - pass + def __str__(self) -> str: + msg = super().__str__() + if not msg and self.args and isinstance(self.args[0], BaseException): + # pdfminer.six raises some exceptions without a message (e.g. + # PDFPasswordIncorrect), which would otherwise be surfaced here + # as a blank error message. + return type(self.args[0]).__name__ + return msg diff --git a/tests/test_basics.py b/tests/test_basics.py index 8691105..dd504fd 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -192,6 +192,14 @@ class Test(unittest.TestCase): with pdfplumber.open(path, password="test") as pdf: assert len(pdf.chars) > 0 + def test_missing_password_message(self): + # pdfminer.six raises some exceptions without a message, which would + # otherwise be re-raised here as a blank PdfminerException. + path = os.path.join(HERE, "pdfs/password-example.pdf") + with pytest.raises(pdfplumber.utils.exceptions.PdfminerException) as exc: + pdfplumber.open(path) + assert "PDFPasswordIncorrect" in str(exc.value) + def test_unicode_normalization(self): path = os.path.join(HERE, "pdfs/issue-905.pdf")