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
3 changes: 0 additions & 3 deletions sqlit/domains/process_worker/app/process_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ def send(self, payload: dict[str, Any]) -> None:
try:
self.conn.send(payload)
return
except OSError:
# Pipe closed; nothing we can do.
return
except Exception as exc:
# Result couldn't be serialized: not picklable, or a driver
# error raised while pickling — e.g. oracledb LOB locators
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/test_process_worker_pickle_safety.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,35 @@ def __reduce__(self) -> Any:
raise RuntimeError("DPY-1001: not connected to database")


class _RaisesOSErrorOnPickle:
"""Simulate serialization code raising an exception also used by pipes."""

def __reduce__(self) -> Any:
raise OSError("LOB read failed")


def test_worker_send_pickle_raising_oserror_emits_error() -> None:
"""An OSError during serialization must not be mistaken for a closed pipe."""
state, parent = _make_state_with_pipe()
try:
payload: dict[str, Any] = {
"type": "result",
"id": 8,
"kind": "query",
"result": _RaisesOSErrorOnPickle(),
}
state.send(payload)

assert parent.poll(timeout=2.0), "client would hang; no error message was sent"
message = parent.recv()
assert message["type"] == "error"
assert message["id"] == 8
assert "LOB read failed" in message["message"]
finally:
parent.close()
state.conn.close()


def test_worker_send_pickle_raising_driver_error_emits_error() -> None:
"""Regression test for issue #276: oracledb CLOB/BLOB results raised
InterfaceError during pickling, which fell through to a bare
Expand Down
Loading