From f2581f0684cbe43fef5d29ea67e7030528cec2c9 Mon Sep 17 00:00:00 2001 From: appleb_m Date: Wed, 3 Jun 2026 16:43:42 +0200 Subject: [PATCH] EXCEPTION REFACTOR: Large scale exception refactor mdipoint, to be tested. If broken scale back this commit and fix tests --- src/aare/common/error_codes.py | 104 +---------------------- src/aare/common/exception_handler.py | 2 +- src/aare/daq/server.py | 4 +- src/aare/gui/threads/daq_worker.py | 2 +- tests/integration/daq/test_daq_server.py | 2 +- tests/unit/common/test_error_codes.py | 2 - 6 files changed, 7 insertions(+), 109 deletions(-) diff --git a/src/aare/common/error_codes.py b/src/aare/common/error_codes.py index b744a140..801cb4f3 100644 --- a/src/aare/common/error_codes.py +++ b/src/aare/common/error_codes.py @@ -30,34 +30,6 @@ class AuthErrorCode(StrEnum): NOT_BATON_HOLDER = "NOT_BATON_HOLDER" -class DAQErrorCode(StrEnum): - """Legacy DAQ error codes -- kept in parallel during the exception-handling - redesign. Will be removed in Phase 9 once GUI no longer references it.""" - BEAMLINE_BUSY = "BEAMLINE_BUSY" - MOUNTING_FAILED = "MOUNTING_FAILED" - UNMOUNTING_FAILED = "UNMOUNTING_FAILED" - LOOP_CENTERING_FAILED = "LOOP_CENTERING_FAILED" - AXC_FAILED = "AXC_FAILED" - TRANSFORMATION_INVALID = "TRANSFORMATION_INVALID" - AUTOMATION_CRITICAL = "AUTOMATION_CRITICAL" - SAMPLE_NOT_FOUND = "SAMPLE_NOT_FOUND" - DATA_COLLECTION_FAILED = "DATA_COLLECTION_FAILED" - RASTER_SCAN_FAILED = "RASTER_SCAN_FAILED" - TELL_WARNING = "TELL_WARNING" - TELL_CRITICAL = "TELL_CRITICAL" - SMARGON_UNAVAILABLE = "SMARGON_UNAVAILABLE" - TELL_UNAVAILABLE = "TELL_UNAVAILABLE" - TELL_CONNECTION_ERROR = "TELL_CONNECTION_ERROR" - TELL_MOUNT_FAILED = "TELL_MOUNT_FAILED" - TELL_BUSY = "TELL_BUSY" - MANUAL_MOUNT_REQUIRED = "MANUAL_MOUNT_REQUIRED" - SMART_MAGNET_FAULT = "SMART_MAGNET_FAULT" - JFJOCH_UNAVAILABLE = "JFJOCH_UNAVAILABLE" - AEROTECH_UNAVAILABLE = "AEROTECH_UNAVAILABLE" - AAREDB_UNAVAILABLE = "AAREDB_UNAVAILABLE" - MAGNET_POSITION_SENSOR_ERROR = "MAGNET_POSITION_SENSOR_ERROR" - - class AareErrorCode(StrEnum): """New error-code enum -- one value per concrete exception class in the AareException hierarchy. @@ -174,78 +146,6 @@ _ERROR_CODE_HELP: dict[str, str] = { AuthErrorCode.INTERNAL_SERVER_ERROR: ( "Unhandled server error. Check server logs for a stack trace and context." ), - DAQErrorCode.BEAMLINE_BUSY: ( - "Beamline state is set to Busy by prior action. If this state persists an additional error may have occurred, " - "preventing the state from being released, this should timeout within 10 minutes." - "If this occurs please seek assistance from your local contact." - ), - DAQErrorCode.MOUNTING_FAILED: ( - "The requested sample could not be mounted. Check TELL/robot state, sample location, and hardware readiness." - ), - DAQErrorCode.UNMOUNTING_FAILED: ( - "The mounted sample could not be unmounted. Check robot state and whether the sample changer is ready." - ), - DAQErrorCode.LOOP_CENTERING_FAILED: ( - "Automatic loop centering failed to locate or position the sample reliably." - ), - DAQErrorCode.AXC_FAILED: ( - "Automatic X-ray centering failed. Verify sample visibility, alignment, and detector/beam conditions." - ), - DAQErrorCode.TRANSFORMATION_INVALID: ( - "The requested beamline state transition is not allowed from the current state." - ), - DAQErrorCode.AUTOMATION_CRITICAL: ( - "A critical failure occurred during fully automated measurement. The GUI should stop " - "dispatching further queue items and staff/operator recovery may be required." - ), - DAQErrorCode.SAMPLE_NOT_FOUND: ( - "The requested sample could not be found in the available sample lists." - ), - DAQErrorCode.DATA_COLLECTION_FAILED: ( - "Rotation/data collection failed before a valid result was produced." - ), - DAQErrorCode.RASTER_SCAN_FAILED: ( - "Raster scan failed before a valid result was produced." - ), - DAQErrorCode.TELL_WARNING: ( - "TELL reported a warning condition. The request may not have completed cleanly." - ), - DAQErrorCode.TELL_CRITICAL: ( - "TELL reported a critical error condition requiring operator attention." - ), - DAQErrorCode.SMARGON_UNAVAILABLE: ( - "Smargon communication failed or the controller is unavailable." - ), - DAQErrorCode.TELL_UNAVAILABLE: ( - "TELL communication failed or the service is unavailable." - ), - DAQErrorCode.TELL_CONNECTION_ERROR: ( - "The server could not establish or maintain a connection to TELL." - ), - DAQErrorCode.TELL_MOUNT_FAILED: ( - "TELL reported that the mount/unmount operation failed." - ), - DAQErrorCode.TELL_BUSY: ( - "A TELL command was requested while TELL was still busy processing another action." - ), - DAQErrorCode.MANUAL_MOUNT_REQUIRED: ( - "Automatic mounting could not proceed and manual intervention is required." - ), - DAQErrorCode.SMART_MAGNET_FAULT: ( - "The smart magnet system reported a fault or unsafe condition." - ), - DAQErrorCode.JFJOCH_UNAVAILABLE: ( - "JFJoch detector communication failed or the detector service is unavailable." - ), - DAQErrorCode.AEROTECH_UNAVAILABLE: ( - "Aerotech communication failed or the motion controller is unavailable." - ), - DAQErrorCode.AAREDB_UNAVAILABLE: ( - "AareDB communication failed or the database service is unavailable." - ), - DAQErrorCode.MAGNET_POSITION_SENSOR_ERROR: ( - "The magnet position sensor reported an invalid or unsafe state." - ), } def error_code_help(code: str) -> str | None: @@ -270,10 +170,10 @@ def export_error_codes_grouped() -> dict[str, dict[str, str]]: { "AuthErrorCode": {"INVALID_TOKEN": "INVALID_TOKEN", ...}, - "DAQErrorCode": {"BEAMLINE_BUSY": "BEAMLINE_BUSY", ...} + "AareErrorCode": {"TELL_COMMUNICATION_ERROR": "TELL_COMMUNICATION_ERROR", ...} } """ - enums: tuple[type[StrEnum], ...] = (AuthErrorCode, DAQErrorCode, AareErrorCode) + enums: tuple[type[StrEnum], ...] = (AuthErrorCode, AareErrorCode) return {e.__name__: {c.name: str(c.value) for c in e} for e in enums} def export_error_codes() -> dict[str, str]: diff --git a/src/aare/common/exception_handler.py b/src/aare/common/exception_handler.py index f94d7daf..9a7f25a3 100644 --- a/src/aare/common/exception_handler.py +++ b/src/aare/common/exception_handler.py @@ -4,7 +4,7 @@ import time from typing import ClassVar from aare.common.logger_config import setup_logger -from aare.common.error_codes import AuthErrorCode, DAQErrorCode +from aare.common.error_codes import AuthErrorCode logger = setup_logger("aareDAQ") diff --git a/src/aare/daq/server.py b/src/aare/daq/server.py index 1a49a4cb..202ef4bd 100644 --- a/src/aare/daq/server.py +++ b/src/aare/daq/server.py @@ -14,7 +14,7 @@ from aareDB import SampleEventType from aare.common.coordinate import AerotechCoordinate from aare.common.auth_models import BatonStatus, BatonRequestStatus from aare.common.coordinate import SmargonCoordinate, Coordinate -from aare.common.error_codes import export_error_codes_grouped, DAQErrorCode +from aare.common.error_codes import export_error_codes_grouped, AareErrorCode from aare.common.logger_config import setup_logger, get_uvicorn_logging_config from aare.common.models import SampleShortInfo, DAQStatusModel, BeamlineStateEnum, BeamlineSettingsModel, \ SampleShortInfoList, SessionStatus, SampleCameraSettings, AutofocusSettings, TokenData, \ @@ -1402,7 +1402,7 @@ async def auto(s: SampleShortInfo, token: str = Depends(oauth2_scheme)): raise HTTPException( status_code=api_status.HTTP_500_INTERNAL_SERVER_ERROR, detail={ - "code": DAQErrorCode.AUTOMATION_CRITICAL.value, + "code": AareErrorCode.INTERNAL_ERROR.value, "message": str(e) or "Critical automation failure", }, ) from e diff --git a/src/aare/gui/threads/daq_worker.py b/src/aare/gui/threads/daq_worker.py index 084e1c9d..cefb5db9 100644 --- a/src/aare/gui/threads/daq_worker.py +++ b/src/aare/gui/threads/daq_worker.py @@ -1772,7 +1772,7 @@ class DAQWorker(QObject): """ Accept either: - flat: {"INVALID_TOKEN": "INVALID_TOKEN"} - - grouped: {"AuthErrorCode": {"INVALID_TOKEN": "INVALID_TOKEN"}, "DAQErrorCode": {...}} + - grouped: {"AuthErrorCode": {"INVALID_TOKEN": "INVALID_TOKEN"}, "AareErrorCode": {...}} Output is always flat strings, using 'Group.KEY' for grouped input. """ diff --git a/tests/integration/daq/test_daq_server.py b/tests/integration/daq/test_daq_server.py index 08df36b8..6edc1197 100644 --- a/tests/integration/daq/test_daq_server.py +++ b/tests/integration/daq/test_daq_server.py @@ -20,7 +20,7 @@ def test_read_error_codes(client): assert response.status_code == 200 data = response.json() assert "AuthErrorCode" in data - assert "DAQErrorCode" in data + assert "AareErrorCode" in data @pytest.mark.integration def test_login_unauthorized(client): diff --git a/tests/unit/common/test_error_codes.py b/tests/unit/common/test_error_codes.py index 41d20780..70545adb 100644 --- a/tests/unit/common/test_error_codes.py +++ b/tests/unit/common/test_error_codes.py @@ -1,6 +1,5 @@ from aare.common.error_codes import ( AuthErrorCode, - DAQErrorCode, AareErrorCode, code_for_exception_class, error_code_help, @@ -79,6 +78,5 @@ def test_code_for_each_concrete_exception_is_in_aare_error_code_enum(): def test_export_error_codes_grouped_includes_aare_error_code(): exported = export_error_codes_grouped() assert "AareErrorCode" in exported - assert "DAQErrorCode" in exported assert "AuthErrorCode" in exported assert "TELL_COMMUNICATION_ERROR" in exported["AareErrorCode"]