Skip to content

Commit 6202feb

Browse files
Cover the add_system(insert_resource=True) path and document the raise
1 parent 2d366d0 commit 6202feb

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

docs/source/architecture/insertion.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ The same pattern applies if you skip the `OSHConnect` convenience and
4444
build a `System` directly: just call `system.insert_self()` and the wrapper
4545
handles dump → POST → ID-capture itself.
4646

47+
If the server rejects the POST, `insert_self()` raises with the status
48+
code and response body rather than returning quietly — otherwise the
49+
system's `_resource_id` would stay `None` and the failure would only
50+
resurface much later, from the first child-resource call that needs it.
51+
4752
## Inserting a Datastream
4853

4954
Similar shape, but the body is wrapped inside a

tests/test_csapi_serialization.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,28 @@ def test_insert_self_raises_on_failed_post(node, monkeypatch):
322322
capture_request(monkeypatch, "post", response=MockResponse(
323323
payload={"error": "disk full"}, status=500))
324324

325-
with pytest.raises(Exception, match=r"Failed to insert system"):
325+
# Status code and response body both belong in the message — they are
326+
# the only diagnostic the caller gets.
327+
with pytest.raises(Exception, match=r"HTTP 500"):
328+
sys.insert_self()
329+
with pytest.raises(Exception, match=r"disk full"):
326330
sys.insert_self()
327331

328332

333+
def test_add_system_does_not_attach_on_failed_insert(node, monkeypatch):
334+
"""The issue's actual repro: `add_system(insert_resource=True)` against
335+
a node that rejects the POST must raise, and must not leave a system
336+
with no server-side id sitting in the node's collection. See GitHub
337+
issue #42."""
338+
sys = System(label="Doomed", urn="urn:test:fail:2", parent_node=node)
339+
340+
capture_request(monkeypatch, "post", response=MockResponse(status=500))
341+
342+
with pytest.raises(Exception, match=r"Failed to insert system"):
343+
node.add_system(sys, insert_resource=True)
344+
assert sys not in node.systems()
345+
346+
329347
def test_resource_id_is_none_before_insert(node):
330348
"""`_resource_id` exists (as None) on every wrapper from construction,
331349
so pre-insert access is a clean None check rather than an

0 commit comments

Comments
 (0)