Skip to content

Commit 2e3508d

Browse files
bot_apkdevin-ai-integration[bot]
andcommitted
refactor: replace default=str fallback with AirbyteTracedException per review
Fail fast with a clear error instead of silently corrupting data by converting non-serializable types to strings. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 8320500 commit 2e3508d

2 files changed

Lines changed: 10 additions & 9 deletions

File tree

airbyte_cdk/entrypoint.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,12 @@ def airbyte_message_to_string(airbyte_message: AirbyteMessage) -> str:
344344
_HAS_LOGGED_FOR_SERIALIZATION_ERROR = True
345345
try:
346346
return json.dumps(serialized_message)
347-
except Exception:
348-
return json.dumps(serialized_message, default=str)
347+
except Exception as json_exception:
348+
raise AirbyteTracedException(
349+
internal_message=f"Failed to serialize AirbyteMessage to JSON: `{json_exception}`",
350+
failure_type=FailureType.system_error,
351+
message=f"A record could not be serialized to JSON: `{json_exception}`. The sync will be stopped to prevent data corruption. Please verify the source is returning valid data types.",
352+
) from json_exception
349353

350354
@classmethod
351355
def extract_state(cls, args: List[str]) -> Optional[Any]:

unit_tests/test_entrypoint.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -858,10 +858,10 @@ def test_given_serialization_error_using_orjson_then_fallback_on_json(
858858
assert len(record_messages) == 2
859859

860860

861-
def test_given_non_json_serializable_type_then_fallback_with_default_str(
861+
def test_given_non_json_serializable_type_then_raise_traced_exception(
862862
entrypoint: AirbyteEntrypoint, mocker, spec_mock, config_mock
863863
):
864-
"""Test that types which both orjson and json cannot serialize (like complex) are handled via default=str fallback."""
864+
"""Test that types which both orjson and json cannot serialize (like complex) raise AirbyteTracedException to prevent data corruption."""
865865
parsed_args = Namespace(
866866
command="read", config="config_path", state="statepath", catalog="catalogpath"
867867
)
@@ -873,8 +873,5 @@ def test_given_non_json_serializable_type_then_fallback_with_default_str(
873873
mocker.patch.object(MockSource, "read_catalog", return_value={})
874874
mocker.patch.object(MockSource, "read", return_value=[record])
875875

876-
messages = list(entrypoint.run(parsed_args))
877-
878-
record_messages = list(filter(lambda message: "RECORD" in message, messages))
879-
assert len(record_messages) == 1
880-
assert "(1+2j)" in record_messages[0]
876+
with pytest.raises(AirbyteTracedException, match="could not be serialized to JSON"):
877+
list(entrypoint.run(parsed_args))

0 commit comments

Comments
 (0)