From 6e7768f965735827586a79e4d3f2e156889770a0 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 8 May 2026 10:12:50 +0000 Subject: [PATCH 1/2] refactor: make changes to auth failed error message --- src/blueapi/utils/numtracker.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/blueapi/utils/numtracker.py b/src/blueapi/utils/numtracker.py index 91e3c66c2a..bb6cccccea 100644 --- a/src/blueapi/utils/numtracker.py +++ b/src/blueapi/utils/numtracker.py @@ -105,6 +105,14 @@ async def create_scan( json = response.json() if json.get("errors") is not None: + for error in json["errors"]: + code = error.get("extensions").get("code") + + if code == "AUTH_FAILED": + raise RuntimeError( + f"Not authorised to create a scan number for " + f"{instrument} and {instrument_session}." + ) raise RuntimeError(f"Numtracker error: {json['errors']}") new_collection = NumtrackerScanMutationResponse.model_validate(json["data"]) From c421585333b2ecf6058ca953c81fddebaf25caef Mon Sep 17 00:00:00 2001 From: root Date: Fri, 8 May 2026 14:04:40 +0000 Subject: [PATCH 2/2] test: add runtime auth error test --- src/blueapi/utils/numtracker.py | 2 +- tests/unit_tests/utils/test_numtracker.py | 28 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/blueapi/utils/numtracker.py b/src/blueapi/utils/numtracker.py index bb6cccccea..ddd489f877 100644 --- a/src/blueapi/utils/numtracker.py +++ b/src/blueapi/utils/numtracker.py @@ -106,7 +106,7 @@ async def create_scan( if json.get("errors") is not None: for error in json["errors"]: - code = error.get("extensions").get("code") + code = (error.get("extensions") or {}).get("code") if code == "AUTH_FAILED": raise RuntimeError( diff --git a/tests/unit_tests/utils/test_numtracker.py b/tests/unit_tests/utils/test_numtracker.py index 859dbaf098..c69ff0b01d 100644 --- a/tests/unit_tests/utils/test_numtracker.py +++ b/tests/unit_tests/utils/test_numtracker.py @@ -33,6 +33,18 @@ def numtracker() -> NumtrackerClient: ], } +AUTH_ERROR = { + "data": None, + "errors": [ + { + "message": "No configuration available for instrument p46", + "locations": [{"line": 3, "column": 5}], + "path": ["scan"], + "extensions": {"code": "AUTH_FAILED"}, + } + ], +} + async def test_create_scan( numtracker: NumtrackerClient, httpx_mock: HTTPXMock, nt_query, nt_response @@ -109,3 +121,19 @@ async def test_create_scan_raises_runtime_error_on_graphql_error( ) with pytest.raises(RuntimeError, match="Numtracker error:"): await numtracker.create_scan("ab123", "p46") + + +async def test_create_scan_raises_runtime_auth_error_on_graphql_error( + numtracker: NumtrackerClient, httpx_mock: HTTPXMock, nt_query +): + httpx_mock.add_response( + method="POST", + url=URL, + match_json=nt_query, + status_code=200, + json=AUTH_ERROR, + ) + with pytest.raises( + RuntimeError, match="Not authorised to create a scan number for p46 and ab123" + ): + await numtracker.create_scan("ab123", "p46")