Skip to content

Commit

Permalink
rest errors
Browse files Browse the repository at this point in the history
  • Loading branch information
pcrespov committed Nov 27, 2024
1 parent 4e829c8 commit f819ffc
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 43 deletions.
44 changes: 42 additions & 2 deletions packages/models-library/src/models_library/rest_error.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,59 @@
from dataclasses import dataclass, field
from typing import Annotated

from pydantic import BaseModel, ConfigDict, Field

from .basic_types import IDStr


@dataclass
class LogMessageType:
# NOTE: deprecated!
message: str
level: str = "INFO"
logger: str = "user"


@dataclass
class ErrorItemType:
# NOTE: deprecated!
code: str
message: str
resource: str | None
field: str | None

@classmethod
def from_error(cls, err: BaseException):
return cls(
code=err.__class__.__name__, message=str(err), resource=None, field=None
)


class ErrorGet(BaseModel):
msg: Annotated[
str, Field(min_length=5, description="Message displayed to the user")
message: Annotated[
str,
Field(
min_length=5,
description="Message displayed to the user",
),
]
support_id: Annotated[
IDStr | None,
Field(description="ID to track the incident during support", alias="supportId"),
] = None

# NOTE: The fields blow are DEPRECATED.
# Still here to keep compatibilty with front-end until updated
status: Annotated[int, Field(deprecated=True)] = 400
errors: Annotated[
list[ErrorItemType],
Field(deprecated=True, default_factory=list, json_schema_extra={"default": []}),
]
logs: Annotated[
list[LogMessageType],
Field(deprecated=True, default_factory=list, json_schema_extra={"default": []}),
]

model_config = ConfigDict(
populate_by_name=True,
extra="ignore", # Used to prune extra fields from internal data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
from aiohttp.web_response import StreamResponse
from common_library.error_codes import create_error_code
from common_library.json_serialization import json_dumps
from models_library.rest_error import ErrorGet, ErrorItemType, LogMessageType

from ..logging_errors import create_troubleshotting_log_kwargs
from ..mimetype_constants import MIMETYPE_APPLICATION_JSON
from ..utils import is_production_environ
from .rest_models import ErrorItemType, ErrorType, LogMessageType
from .rest_responses import (
create_data_response,
create_http_error,
Expand Down Expand Up @@ -98,7 +98,7 @@ async def _middleware_handler(request: web.Request, handler: Handler):
err.content_type = MIMETYPE_APPLICATION_JSON

if not err.text or not is_enveloped_from_text(err.text):
error = ErrorType(
error = ErrorGet(
errors=[
ErrorItemType.from_error(err),
],
Expand Down
30 changes: 0 additions & 30 deletions packages/service-library/src/servicelib/aiohttp/rest_models.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
import inspect
import json
from collections.abc import Mapping
from dataclasses import asdict
from typing import Any

from aiohttp import web, web_exceptions
from aiohttp.web_exceptions import HTTPError, HTTPException
from common_library.json_serialization import json_dumps
from models_library.rest_error import ErrorGet, ErrorItemType
from servicelib.aiohttp.status import HTTP_200_OK

from ..mimetype_constants import MIMETYPE_APPLICATION_JSON
from ..status_codes_utils import get_code_description
from .rest_models import ErrorItemType, ErrorType

_ENVELOPE_KEYS = ("data", "error")

Expand Down Expand Up @@ -101,21 +100,23 @@ def create_http_error(
default_message = reason or get_code_description(http_error_cls.status_code)

if is_internal_error and skip_internal_error_details:
error = ErrorType(
error = ErrorGet(
errors=[],
logs=[],
status=http_error_cls.status_code,
message=default_message,
)
else:
items = [ErrorItemType.from_error(err) for err in errors]
error = ErrorType(
error = ErrorGet(
errors=items,
logs=[],
status=http_error_cls.status_code,
message=default_message,
)

assert not http_error_cls.empty_body # nosec
payload = wrap_as_envelope(error=asdict(error))
payload = wrap_as_envelope(error=error)

return http_error_cls(
reason=reason,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def create_error_response(error: ErrorGet, status_code: int) -> web.Response:
return web.json_response(
data={"error": error.model_dump(exclude_unset=True, mode="json")},
dumps=json_dumps,
reason=error.msg,
reason=error.message,
status=status_code,
)

Expand Down Expand Up @@ -81,7 +81,7 @@ async def _exception_handler(
_DefaultDict(getattr(exception, "__dict__", {}))
)

error = ErrorGet(msg=user_msg)
error = ErrorGet(message=user_msg)

if is_5xx_server_error(status_code):
oec = create_error_code(exception)
Expand All @@ -98,7 +98,7 @@ async def _exception_handler(
},
)
)
error = ErrorGet(msg=user_msg, support_id=IDStr(oec))
error = ErrorGet(message=user_msg, support_id=IDStr(oec))

return create_error_response(error, status_code=status_code)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
from aiohttp import web
from common_library.json_serialization import json_dumps
from models_library.products import ProductName
from models_library.rest_error import LogMessageType
from models_library.users import UserID
from pydantic import PositiveInt
from servicelib.aiohttp import observer
from servicelib.aiohttp.rest_models import LogMessageType
from servicelib.aiohttp.status import HTTP_200_OK
from servicelib.mimetype_constants import MIMETYPE_APPLICATION_JSON
from simcore_postgres_database.models.users import UserRole
Expand Down

0 comments on commit f819ffc

Please sign in to comment.