spakky-fastapi 1.6.2__tar.gz → 1.6.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spakky-fastapi
3
- Version: 1.6.2
3
+ Version: 1.6.3
4
4
  Summary: Highly abstracted Framework core to use DDD & DI/IoC & AOP & Etc...
5
5
  Author: Spakky
6
6
  Author-email: sejong418@icloud.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "spakky-fastapi"
3
- version = "1.6.2"
3
+ version = "1.6.3"
4
4
  description = "Highly abstracted Framework core to use DDD & DI/IoC & AOP & Etc..."
5
5
  authors = ["Spakky <sejong418@icloud.com>"]
6
6
  readme = "README.md"
@@ -24,8 +24,8 @@ pytest = "^7.4.3"
24
24
  pytest-cov = "^4.1.0"
25
25
  pytest-asyncio = "^0.21.1"
26
26
  httpx = "^0.26.0"
27
-
28
27
  toml = "^0.10.2"
28
+
29
29
  [tool.poetry.group.ci.dependencies]
30
30
  pylint = "^3.0.2"
31
31
  pytest = "^7.4.3"
@@ -0,0 +1,65 @@
1
+ from typing import ClassVar
2
+
3
+ from fastapi import status
4
+ from fastapi.responses import ORJSONResponse
5
+ from spakky.core.error import SpakkyCoreError
6
+
7
+
8
+ class SpakkyFastAPIError(SpakkyCoreError):
9
+ status_code: ClassVar[int]
10
+
11
+ def __init__(self, error: SpakkyCoreError) -> None:
12
+ self.message = error.message
13
+ self.args = error.args
14
+
15
+ def to_response(self) -> ORJSONResponse:
16
+ return ORJSONResponse(
17
+ content={
18
+ "message": self.message,
19
+ "args": [str(x) for x in self.args],
20
+ },
21
+ status_code=self.status_code,
22
+ )
23
+
24
+
25
+ class SpakkyUnknownError(SpakkyCoreError):
26
+ message = "알 수 없는 오류가 발생했습니다."
27
+
28
+
29
+ class BadRequest(SpakkyFastAPIError):
30
+ status_code: ClassVar[int] = status.HTTP_400_BAD_REQUEST
31
+
32
+
33
+ class Unauthorized(SpakkyFastAPIError):
34
+ status_code: ClassVar[int] = status.HTTP_401_UNAUTHORIZED
35
+
36
+
37
+ class Forbidden(SpakkyFastAPIError):
38
+ status_code: ClassVar[int] = status.HTTP_403_FORBIDDEN
39
+
40
+
41
+ class NotFound(SpakkyFastAPIError):
42
+ status_code: ClassVar[int] = status.HTTP_404_NOT_FOUND
43
+
44
+
45
+ class Conflict(SpakkyFastAPIError):
46
+ status_code: ClassVar[int] = status.HTTP_409_CONFLICT
47
+
48
+
49
+ class InternalServerError(SpakkyFastAPIError):
50
+ status_code: ClassVar[int] = status.HTTP_500_INTERNAL_SERVER_ERROR
51
+ stacktrace: str | None
52
+
53
+ def __init__(self, error: Exception, stacktrace: str | None) -> None:
54
+ super().__init__(SpakkyUnknownError(error.args))
55
+ self.stacktrace = stacktrace
56
+
57
+ def to_response(self) -> ORJSONResponse:
58
+ return ORJSONResponse(
59
+ content={
60
+ "message": self.message,
61
+ "args": [str(x) for x in self.args],
62
+ "stacktrace": self.stacktrace,
63
+ },
64
+ status_code=self.status_code,
65
+ )
@@ -2,8 +2,6 @@ import traceback
2
2
  from typing import Callable, Awaitable, TypeAlias
3
3
 
4
4
  from fastapi import Request
5
- from fastapi.responses import ORJSONResponse
6
- from pydantic import BaseModel
7
5
  from starlette.middleware.base import BaseHTTPMiddleware, DispatchFunction
8
6
  from starlette.responses import Response
9
7
  from starlette.types import ASGIApp
@@ -13,12 +11,6 @@ from spakky_fastapi.error import InternalServerError, SpakkyFastAPIError
13
11
  Next: TypeAlias = Callable[[Request], Awaitable[Response]]
14
12
 
15
13
 
16
- class ErrorResponse(BaseModel):
17
- message: str
18
- args: list[str]
19
- traceback: str = ""
20
-
21
-
22
14
  class ErrorHandlingMiddleware(BaseHTTPMiddleware):
23
15
  __debug: bool
24
16
 
@@ -35,23 +27,11 @@ class ErrorHandlingMiddleware(BaseHTTPMiddleware):
35
27
  try:
36
28
  return await call_next(request)
37
29
  except SpakkyFastAPIError as e:
38
- return ORJSONResponse(
39
- content=ErrorResponse(
40
- message=e.message,
41
- args=[str(x) for x in e.args],
42
- ).model_dump(),
43
- status_code=e.status_code,
44
- )
45
- # pylint: disable=broad-exception-caught
46
- except Exception as e:
30
+ return e.to_response()
31
+ except Exception as e: # pylint: disable=broad-exception-caught
47
32
  if self.__debug:
48
33
  traceback.print_exc() # pragma: no cover
49
- error = InternalServerError(e)
50
- return ORJSONResponse(
51
- content=ErrorResponse(
52
- message=error.message,
53
- args=[str(x) for x in error.args],
54
- traceback=error.traceback if self.__debug else "",
55
- ).model_dump(),
56
- status_code=error.status_code,
57
- )
34
+ return InternalServerError(
35
+ error=e,
36
+ stacktrace=traceback.format_exc() if self.__debug else None,
37
+ ).to_response()
@@ -1,45 +0,0 @@
1
- import traceback
2
-
3
- from fastapi import status
4
- from spakky.core.error import SpakkyCoreError
5
-
6
-
7
- class SpakkyFastAPIError(SpakkyCoreError):
8
- status_code: int
9
-
10
- def __init__(self, error: SpakkyCoreError) -> None:
11
- self.message = error.message
12
- self.args = error.args
13
-
14
-
15
- class SpakkyUnknownError(SpakkyCoreError):
16
- message = "알 수 없는 오류가 발생했습니다."
17
-
18
-
19
- class BadRequest(SpakkyFastAPIError):
20
- status_code: int = status.HTTP_400_BAD_REQUEST
21
-
22
-
23
- class Unauthorized(SpakkyFastAPIError):
24
- status_code: int = status.HTTP_401_UNAUTHORIZED
25
-
26
-
27
- class Forbidden(SpakkyFastAPIError):
28
- status_code: int = status.HTTP_403_FORBIDDEN
29
-
30
-
31
- class NotFound(SpakkyFastAPIError):
32
- status_code: int = status.HTTP_404_NOT_FOUND
33
-
34
-
35
- class Conflict(SpakkyFastAPIError):
36
- status_code: int = status.HTTP_409_CONFLICT
37
-
38
-
39
- class InternalServerError(SpakkyFastAPIError):
40
- status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR
41
- traceback: str = ""
42
-
43
- def __init__(self, error: Exception) -> None:
44
- super().__init__(SpakkyUnknownError(error.args))
45
- self.traceback = traceback.format_exc()
File without changes