Repository: deepset-ai/haystack

Issue:
LazyImport ImportError message might be clearer
When an optional dependency is not installed and required by some component, we raise an error message.
Generally, the error message contains simple instructions to install the missing dependency.

```python
from haystack.components.converters import PyPDFToDocument

converter = PyPDFToDocument()
```

```... ImportError: Failed to import 'pypdf'. Run 'pip install pypdf'. Original error: No module named 'pypdf'```

We received the feedback that the error message could be made clearer, explaining that the optional dependency is missing. Something like

```... ImportError: "Haystack failed to import the optional dependency 'pypdf'. Run 'pip install pypdf'. Original error: No module named 'pypdf'```

(@mpangrazzi)



Discussion:
The error message has been improved in #9667.

@dfokina can we add to the [installation docs](https://docs.haystack.deepset.ai/docs/installation) a simple section like the following?

### Optional dependencies

Some components in Haystack rely on additional, optional dependencies.
To keep the installation lightweight, these are not included by default: only the essentials are installed.
If you use a feature that requires an optional dependency that hasn't been installed, Haystack will raise an error like:
`ImportError: "Haystack failed to import the optional dependency 'pypdf'. Run 'pip install pypdf'.`



Patch:
diff --git a/haystack/lazy_imports.py b/haystack/lazy_imports.py
index b5a1feba62..54bb659253 100644
--- a/haystack/lazy_imports.py
+++ b/haystack/lazy_imports.py
@@ -46,8 +46,8 @@ def __exit__(
         """
         if isinstance(exc_value, ImportError):
             message = (
-                f"Failed to import '{exc_value.name}'. {self.import_error_msg.format(exc_value.name)}. "
-                f"Original error: {exc_value}"
+                f"Haystack failed to import the optional dependency '{exc_value.name}'. "
+                f"{self.import_error_msg.format(exc_value.name)}. Original error: {exc_value}"
             )
             self._deferred = (exc_value, message)
             return True
diff --git a/releasenotes/notes/improve-lazy-import-err-msg-cc603e5ff5ac8b0e.yaml b/releasenotes/notes/improve-lazy-import-err-msg-cc603e5ff5ac8b0e.yaml
new file mode 100644
index 0000000000..7f97622518
--- /dev/null
+++ b/releasenotes/notes/improve-lazy-import-err-msg-cc603e5ff5ac8b0e.yaml
@@ -0,0 +1,4 @@
+---
+enhancements:
+  - |
+    Made the lazy import error message clearer explaining that the optional dependency is missing.


Test patch:
diff --git a/test/test_lazy_imports.py b/test/test_lazy_imports.py
new file mode 100644
index 0000000000..b7d8043b30
--- /dev/null
+++ b/test/test_lazy_imports.py
@@ -0,0 +1,22 @@
+# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
+#
+# SPDX-License-Identifier: Apache-2.0
+
+import pytest
+
+from haystack.lazy_imports import DEFAULT_IMPORT_ERROR_MSG, LazyImport
+
+
+class TestLazyImport:
+    def test_import_error_is_suppressed_and_deferred(self):
+        with LazyImport() as lazy_import:
+            import a_module
+
+        assert lazy_import._deferred is not None
+        exc_value, message = lazy_import._deferred
+        assert isinstance(exc_value, ImportError)
+        expected_message = (
+            "Haystack failed to import the optional dependency 'a_module'. Try 'pip install a_module'. "
+            "Original error: No module named 'a_module'"
+        )
+        assert expected_message in message