Exceptions: added handling for tellcommunication and smargon communication errors
This commit is contained in:
1 parent
02f2eead57
commit
c54d3c1f1e
2 files changed
+105
-3
No files matched your search
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from aare.common.logger_config import setup_logger
|
||||
from aare.common.error_codes import AuthErrorCode
|
||||
from aare.common.error_codes import AuthErrorCode, DAQErrorCode
|
||||
|
||||
logger = setup_logger("aareDAQ")
|
||||
|
||||
@@ -64,6 +64,7 @@ class AXCFailed(Exception):
|
||||
def __str__(self) -> str:
|
||||
return self.message
|
||||
|
||||
|
||||
class BeamlineBusyException(Exception):
|
||||
def __init__(self, message: str = "Beamline is in busy state"):
|
||||
super().__init__(message)
|
||||
@@ -73,6 +74,7 @@ class BeamlineBusyException(Exception):
|
||||
def __str__(self) -> str:
|
||||
return self.message
|
||||
|
||||
|
||||
class SampleException(Exception):
|
||||
def __init__(self, message: str = "Sample not found"):
|
||||
super().__init__(message)
|
||||
@@ -82,6 +84,7 @@ class SampleException(Exception):
|
||||
def __str__(self) -> str:
|
||||
return self.message
|
||||
|
||||
|
||||
class AuthenticationException(Exception):
|
||||
def __init__(self,
|
||||
message: str = "Authentication failed.",
|
||||
@@ -99,6 +102,7 @@ class AuthenticationException(Exception):
|
||||
def __str__(self) -> str:
|
||||
return self.message
|
||||
|
||||
|
||||
class UserRightsException(Exception):
|
||||
def __init__(self,
|
||||
message: str = "User does not have rights to perform this action.",
|
||||
@@ -113,5 +117,74 @@ class UserRightsException(Exception):
|
||||
self.code = code
|
||||
logger.error(message, extra={"exception:": Exception})
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.message
|
||||
|
||||
|
||||
class SmargonCommunicationError(Exception):
|
||||
"""
|
||||
Raised when Smargon HTTP communication fails (connection refused, timeout, bad HTTP status, etc).
|
||||
Keep the original exception in `__cause__` by using `raise ... from e`.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: str = "Smargon communication error",
|
||||
*,
|
||||
endpoint: str | None = None,
|
||||
base_url: str | None = None,
|
||||
operation: str | None = None, # e.g. "GET" / "PUT"
|
||||
status_code: int | None = None,
|
||||
):
|
||||
super().__init__(message)
|
||||
self.message = message
|
||||
self.endpoint = endpoint
|
||||
self.base_url = base_url
|
||||
self.operation = operation
|
||||
self.status_code = status_code
|
||||
logger.error(
|
||||
message,
|
||||
extra={
|
||||
"device": "smargon",
|
||||
"operation": operation,
|
||||
"endpoint": endpoint,
|
||||
"base_url": base_url,
|
||||
"status_code": status_code,
|
||||
},
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.message
|
||||
|
||||
|
||||
class TellCommunicationError(Exception):
|
||||
"""
|
||||
Raised when TELL HTTP/PShell communication fails (timeouts, connection refused, etc).
|
||||
Intended to be caught centrally by FastAPI exception handlers.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
message: str = "TELL communication error",
|
||||
*,
|
||||
endpoint: str | None = None,
|
||||
base_url: str | None = None,
|
||||
operation: str | None = None, # e.g. "GET"
|
||||
):
|
||||
super().__init__(message)
|
||||
self.message = message
|
||||
self.endpoint = endpoint
|
||||
self.base_url = base_url
|
||||
self.operation = operation
|
||||
logger.error(
|
||||
message,
|
||||
extra={
|
||||
"device": "tell",
|
||||
"operation": operation,
|
||||
"endpoint": endpoint,
|
||||
"base_url": base_url,
|
||||
},
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.message
|
||||
@@ -16,7 +16,8 @@ from aare.common.exception_handler import (
|
||||
BeamlineBusyException,
|
||||
AuthenticationException,
|
||||
SampleException,
|
||||
UserRightsException
|
||||
UserRightsException,
|
||||
SmargonCommunicationError, TellCommunicationError
|
||||
)
|
||||
|
||||
logger = setup_logger("aareDAQ")
|
||||
@@ -116,10 +117,38 @@ def register_exception_handlers(app) -> None:
|
||||
content=_error_payload(code="SAMPLE_NOT_FOUND", message=str(exc) or "Sample not found"),
|
||||
)
|
||||
|
||||
@app.exception_handler(SmargonCommunicationError)
|
||||
async def smargon_comm_handler(request: Request, exc: SmargonCommunicationError) -> JSONResponse:
|
||||
return JSONResponse(
|
||||
status_code=api_status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
content=_error_payload(
|
||||
code="SMARGON_UNAVAILABLE",
|
||||
message=str(exc) or "Smargon is unavailable",
|
||||
extra={
|
||||
"operation": getattr(exc, "operation", None),
|
||||
"endpoint": getattr(exc, "endpoint", None),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
@app.exception_handler(TellCommunicationError)
|
||||
async def tell_comm_handler(request: Request, exc: TellCommunicationError) -> JSONResponse:
|
||||
return JSONResponse(
|
||||
status_code=api_status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
content=_error_payload(
|
||||
code="TELL_UNAVAILABLE",
|
||||
message=str(exc) or "TELL is unavailable",
|
||||
extra={
|
||||
"operation": getattr(exc, "operation", None),
|
||||
"endpoint": getattr(exc, "endpoint", None),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
@app.exception_handler(Exception)
|
||||
async def unhandled_exception_handler(request: Request, exc: Exception) -> JSONResponse:
|
||||
logger.exception("Unhandled server exception")
|
||||
return JSONResponse(
|
||||
status_code=api_status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
content=_error_payload(code="INTERNAL_SERVER_ERROR", message="Internal server error"),
|
||||
content=_error_payload(code="INTERNAL_SERVER_ERROR", message=str(exc) or "Internal server error"),
|
||||
)
|
||||
Reference in new issue
Block a user