Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion haystack/components/converters/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,15 @@ def _get_content_and_meta(self, source: ByteStream) -> list[tuple[str, dict[str,
else:
# We just load the whole file as JSON if the user didn't provide a jq filter.
# We put it in a list even if it's not to ease handling it later on.
objects = [json.loads(file_content)]
try:
objects = [json.loads(file_content)]
except json.JSONDecodeError as exc:
logger.warning(
"Failed to extract text from {source}. Skipping it. Error: {error}",
source=source.meta["file_path"],
error=exc,
)
return []

result = []
if self._content_key is not None:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
Fixed ``JSONConverter`` crashing on a malformed JSON source when it is
configured with ``content_key`` and no ``jq_schema``. The non-jq branch
called ``json.loads`` without a guard, so a single invalid ``.json`` file
raised an unhandled ``JSONDecodeError`` and aborted the whole run. Invalid
JSON is now caught, logged, and skipped, matching the behavior of the
``jq_schema`` path.
17 changes: 17 additions & 0 deletions test/components/converters/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,23 @@ def test_run_with_bad_encoding(tmpdir, caplog):
assert result == {"documents": []}


def test_run_with_malformed_json_and_content_key(tmpdir, caplog):
test_file = Path(tmpdir / "test_file.json")
test_file.write_text("This is not valid JSON.", "utf-8")

sources = [test_file]
converter = JSONConverter(content_key="motivation")

caplog.clear()
with caplog.at_level(logging.WARNING):
result = converter.run(sources=sources)

records = caplog.records
assert len(records) == 1
assert records[0].msg.startswith(f"Failed to extract text from {test_file}. Skipping it. Error:")
assert result == {"documents": []}


def test_run_with_single_meta(tmpdir):
first_test_file = Path(tmpdir / "first_test_file.json")
second_test_file = Path(tmpdir / "second_test_file.json")
Expand Down
Loading