EXCEPTION REFACTOR: Large scale exception refactor mdipoint, to be tested. If broken scale back this commit and fix tests
Build and Publish / test (push) Successful in 1m30s
Build and Publish / build (push) Successful in 18s
Build and Publish / Build and Deploy Docs (push) Successful in 39s

This commit is contained in:
2026-06-03 16:43:42 +02:00
parent c6ee5560a0
commit f2581f0684
6 changed files with 7 additions and 109 deletions
+2 -102
View File
@@ -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]:
+1 -1
View File
@@ -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")
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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.
"""
+1 -1
View File
@@ -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):
-2
View File
@@ -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"]