Skip to content

Commit 6f741e9

Browse files
committed
eneveloped error
1 parent ceec907 commit 6f741e9

File tree

3 files changed

+57
-40
lines changed

3 files changed

+57
-40
lines changed

api/specs/web-server/_common.py

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,22 @@
55
import sys
66
from collections.abc import Callable
77
from pathlib import Path
8-
from typing import Annotated, NamedTuple, Optional, Union, get_args, get_origin
8+
from typing import (
9+
Annotated,
10+
Any,
11+
Generic,
12+
NamedTuple,
13+
Optional,
14+
TypeVar,
15+
Union,
16+
get_args,
17+
get_origin,
18+
)
919

1020
from common_library.json_serialization import json_dumps
1121
from common_library.pydantic_fields_extension import get_type
1222
from fastapi import Query
13-
from models_library.basic_types import LogLevel
14-
from pydantic import BaseModel, ConfigDict, Field, Json, create_model
23+
from pydantic import BaseModel, Json, create_model
1524
from pydantic.fields import FieldInfo
1625

1726
CURRENT_DIR = Path(sys.argv[0] if __name__ == "__main__" else __file__).resolve().parent
@@ -78,43 +87,12 @@ def as_query(model_class: type[BaseModel]) -> type[BaseModel]:
7887
return create_model(new_model_name, **fields)
7988

8089

81-
class Log(BaseModel):
82-
level: LogLevel | None = Field("INFO", description="log level")
83-
message: str = Field(
84-
...,
85-
description="log message. If logger is USER, then it MUST be human readable",
86-
)
87-
logger: str | None = Field(
88-
None, description="name of the logger receiving this message"
89-
)
90-
91-
model_config = ConfigDict(
92-
json_schema_extra={
93-
"example": {
94-
"message": "Hi there, Mr user",
95-
"level": "INFO",
96-
"logger": "user-logger",
97-
}
98-
}
99-
)
100-
101-
102-
class ErrorItem(BaseModel):
103-
code: str = Field(
104-
...,
105-
description="Typically the name of the exception that produced it otherwise some known error code",
106-
)
107-
message: str = Field(..., description="Error message specific to this item")
108-
resource: str | None = Field(
109-
None, description="API resource affected by this error"
110-
)
111-
field: str | None = Field(None, description="Specific field within the resource")
90+
ErrorT = TypeVar("ErrorT")
11291

11392

114-
class Error(BaseModel):
115-
logs: list[Log] | None = Field(None, description="log messages")
116-
errors: list[ErrorItem] | None = Field(None, description="errors metadata")
117-
status: int | None = Field(None, description="HTTP error code")
93+
class EnvelopeE(BaseModel, Generic[ErrorT]):
94+
error: ErrorT | None = None
95+
data: Any | None = None
11896

11997

12098
class ParamSpec(NamedTuple):

api/specs/web-server/_folders.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@
99

1010
from typing import Annotated
1111

12-
from _common import as_query
12+
from _common import EnvelopeE, as_query
1313
from fastapi import APIRouter, Depends, status
1414
from models_library.api_schemas_webserver.folders_v2 import (
1515
FolderCreateBodyParams,
1616
FolderGet,
1717
FolderReplaceBodyParams,
1818
)
1919
from models_library.generics import Envelope
20+
from models_library.rest_error import ErrorGet
2021
from simcore_service_webserver._meta import API_VTAG
22+
from simcore_service_webserver.folders._exceptions_handlers import _TO_HTTP_ERROR_MAP
2123
from simcore_service_webserver.folders._models import (
2224
FolderSearchQueryParams,
2325
FoldersListQueryParams,
@@ -29,6 +31,10 @@
2931
tags=[
3032
"folders",
3133
],
34+
responses={
35+
i.status_code: {"model": EnvelopeE[ErrorGet]}
36+
for i in _TO_HTTP_ERROR_MAP.values()
37+
},
3238
)
3339

3440

packages/models-library/src/models_library/rest_error.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,40 @@
33

44
from pydantic import BaseModel, ConfigDict, Field
55

6-
from .basic_types import IDStr
6+
from .basic_types import IDStr, LogLevel
7+
8+
9+
class Log(BaseModel):
10+
level: LogLevel | None = Field("INFO", description="log level")
11+
message: str = Field(
12+
...,
13+
description="log message. If logger is USER, then it MUST be human readable",
14+
)
15+
logger: str | None = Field(
16+
None, description="name of the logger receiving this message"
17+
)
18+
19+
model_config = ConfigDict(
20+
json_schema_extra={
21+
"example": {
22+
"message": "Hi there, Mr user",
23+
"level": "INFO",
24+
"logger": "user-logger",
25+
}
26+
}
27+
)
28+
29+
30+
class ErrorItem(BaseModel):
31+
code: str = Field(
32+
...,
33+
description="Typically the name of the exception that produced it otherwise some known error code",
34+
)
35+
message: str = Field(..., description="Error message specific to this item")
36+
resource: str | None = Field(
37+
None, description="API resource affected by this error"
38+
)
39+
field: str | None = Field(None, description="Specific field within the resource")
740

841

942
@dataclass

0 commit comments

Comments
 (0)