fix(api/topology): map duplicate-name IntegrityError to 409

POST /topologies raised a 500 with a raw SQLAlchemy IntegrityError
traceback when the name collided with an existing topology. Catch
the error at the router, verify it's the ix_topologies_name
constraint (so unrelated integrity failures still surface as 500s
with their real traceback), and return 409 with a helpful detail.

Test covers the create-then-duplicate-create flow.
This commit is contained in:
2026-04-24 19:06:37 -04:00
parent 9bed930497
commit c214cdd7bb
2 changed files with 37 additions and 2 deletions

View File

@@ -80,6 +80,27 @@ async def test_create_requires_auth(client):
assert r.status_code == 401
@pytest.mark.anyio
async def test_create_duplicate_name_is_409(client, auth_token):
"""Re-using an existing topology name must return a clean 409, not
bubble the raw MySQL IntegrityError up to a 500."""
payload = _generate_payload()
first = await client.post(
f"{_V1}/",
json=payload,
headers={"Authorization": f"Bearer {auth_token}"},
)
assert first.status_code == 201, first.text
second = await client.post(
f"{_V1}/",
json=payload,
headers={"Authorization": f"Bearer {auth_token}"},
)
assert second.status_code == 409, second.text
assert payload["name"] in second.json()["detail"]
@pytest.mark.anyio
async def test_create_bad_body(client, auth_token):
r = await client.post(