Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All errors in dynamic-sidecar inherit from OsparcErrorMixin #6764

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ async def get_volume_by_label(label: str, run_id: RunID) -> dict[str, Any]:
volumes = data["Volumes"]
_logger.debug("volumes query for label=%s volumes=%s", label, volumes)
if len(volumes) != 1:
raise VolumeNotFoundError(label, run_id, volumes)
raise VolumeNotFoundError(
volume_count=len(volumes),
source_label=label,
run_id=run_id,
volume_names=" ".join(v.get("Name", "UNKNOWN") for v in volumes),
status_code=http_status.HTTP_404_NOT_FOUND,
)
volume_details: dict[str, Any] = volumes[0]
return volume_details

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async def http_error_handler(
) -> JSONResponse:
return JSONResponse(
content=jsonable_encoder({"errors": [exception.message]}),
status_code=exception.status_code,
status_code=exception.status_code, # type:ignore[attr-defined]
)


Expand Down
Original file line number Diff line number Diff line change
@@ -1,53 +1,30 @@
from typing import Any

from common_library.errors_classes import OsparcErrorMixin
from fastapi import status
from models_library.services import RunID


class BaseDynamicSidecarError(Exception):
class BaseDynamicSidecarError(OsparcErrorMixin, Exception):
"""Used as base for all exceptions"""

def __init__(
self, nessage: str, status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR
) -> None:
self.message: str = nessage
self.status_code: int = status_code
super().__init__(nessage)


class VolumeNotFoundError(BaseDynamicSidecarError):
def __init__(
self, source_label: str, run_id: RunID, volumes: list[dict[str, Any]]
) -> None:
super().__init__(
f"Expected 1 got {len(volumes)} volumes labels with {source_label=}, {run_id=}: "
f"Found {' '.join(v.get('Name', 'UNKNOWN') for v in volumes)}",
status_code=status.HTTP_404_NOT_FOUND,
)
msg_template = (
"Expected 1 got {volume_count} volumes labels with "
"source_label={source_label}, run_id={run_id}: Found {volume_names}"
)


class UnexpectedDockerError(BaseDynamicSidecarError):
def __init__(self, message: str, status_code: int) -> None:
super().__init__(
f"An unexpected Docker error occurred {status_code=}, {message=}",
status_code=status_code,
)


class BaseError(OsparcErrorMixin, BaseDynamicSidecarError):
...
msg_template = "An unexpected Docker error occurred status_code={status_code}, message={message}"


class ContainerExecContainerNotFoundError(BaseError):
class ContainerExecContainerNotFoundError(BaseDynamicSidecarError):
msg_template = "Container '{container_name}' was not found"


class ContainerExecTimeoutError(BaseError):
class ContainerExecTimeoutError(BaseDynamicSidecarError):
msg_template = "Timed out after {timeout} while executing: '{command}'"


class ContainerExecCommandFailedError(BaseError):
class ContainerExecCommandFailedError(BaseDynamicSidecarError):
msg_template = (
"Command '{command}' exited with code '{exit_code}'"
"and output: '{command_result}'"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import cast

from common_library.pydantic_validators import validate_numeric_string_as_timedelta
from models_library.basic_types import BootModeEnum, PortInt
from models_library.basic_types import PortInt
from models_library.callbacks_mapping import CallbacksMapping
from models_library.products import ProductName
from models_library.projects import ProjectID
Expand All @@ -21,8 +21,8 @@
field_validator,
)
from servicelib.logging_utils_filtering import LoggerName, MessageSubstring
from settings_library.application import BaseApplicationSettings
from settings_library.aws_s3_cli import AwsS3CliSettings
from settings_library.base import BaseCustomSettings
from settings_library.docker_registry import RegistrySettings
from settings_library.node_ports import StorageAuthSettings
from settings_library.postgres import PostgresSettings
Expand All @@ -35,7 +35,7 @@
from settings_library.utils_logging import MixinLoggingSettings


class ResourceTrackingSettings(BaseCustomSettings):
class ResourceTrackingSettings(BaseApplicationSettings):
RESOURCE_TRACKING_HEARTBEAT_INTERVAL: timedelta = Field(
default=DEFAULT_RESOURCE_USAGE_HEARTBEAT_INTERVAL,
description="each time the status of the service is propagated",
Expand All @@ -46,17 +46,13 @@ class ResourceTrackingSettings(BaseCustomSettings):
)


class SystemMonitorSettings(BaseCustomSettings):
class SystemMonitorSettings(BaseApplicationSettings):
DY_SIDECAR_SYSTEM_MONITOR_TELEMETRY_ENABLE: bool = Field(
default=False, description="enabled/disabled disk usage monitoring"
)


class ApplicationSettings(BaseCustomSettings, MixinLoggingSettings):
SC_BOOT_MODE: BootModeEnum = Field(
...,
description="boot mode helps determine if in development mode or normal operation",
)
class ApplicationSettings(BaseApplicationSettings, MixinLoggingSettings):

DYNAMIC_SIDECAR_DY_VOLUMES_MOUNT_DIR: Path = Field(
...,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ async def test_container_docker_error(
def _expected_error_string(status_code: int) -> dict[str, Any]:
return {
"errors": [
f"An unexpected Docker error occurred status_code={status_code}, message='aiodocker_mocked_error'"
f"An unexpected Docker error occurred status_code={status_code}, message=aiodocker_mocked_error"
]
}

Expand Down
42 changes: 42 additions & 0 deletions services/dynamic-sidecar/tests/unit/test_core_errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# pylint:disable=broad-exception-caught
# pylint:disable=no-member

from simcore_service_dynamic_sidecar.core.errors import (
UnexpectedDockerError,
VolumeNotFoundError,
)
from starlette import status


def test_legacy_interface_unexpected_docker_error():
message = "some_message"
status_code = 42
try:
raise UnexpectedDockerError( # noqa: TRY301
message=message, status_code=status_code
)
except Exception as e:
print(e)
assert e.status_code == status_code # noqa: PT017
assert message in e.message # noqa: PT017


def test_legacy_interface_volume_not_found_error():
try:
volumes = [{}, {"Name": "a_volume"}]
volume_names = " ".join(v.get("Name", "UNKNOWN") for v in volumes)

raise VolumeNotFoundError( # noqa: TRY301
volume_count=len(volumes),
source_label="some",
run_id="run_id",
volume_names=volume_names,
status_code=status.HTTP_404_NOT_FOUND,
)
except Exception as e:
print(e)
assert ( # noqa: PT017
e.message
== "Expected 1 got 2 volumes labels with source_label=some, run_id=run_id: Found UNKNOWN a_volume"
GitHK marked this conversation as resolved.
Show resolved Hide resolved
)
assert e.status_code == status.HTTP_404_NOT_FOUND # noqa: PT017
Loading