Skip to content

Commit 61147d4

Browse files
authored
Fix background task not executed (#86)
* Fix login auth failure exception * Add background task to custom exception class * Fix branch conflicts * Update login log status to enum.
1 parent 14e1e20 commit 61147d4

File tree

5 files changed

+52
-28
lines changed

5 files changed

+52
-28
lines changed

backend/app/common/enums.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,10 @@ class MethodType(StrEnum):
4848
PUT = 'PUT'
4949
DELETE = 'DELETE'
5050
PATCH = 'PATCH'
51+
52+
53+
class LoginLogStatus(IntEnum):
54+
"""登陆日志状态"""
55+
56+
fail = 0
57+
success = 1

backend/app/common/exception/errors.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@
33
from typing import Any
44

55
from fastapi import HTTPException
6+
from starlette.background import BackgroundTask
67

78
from backend.app.common.response.response_code import CustomCode
89

910

1011
class BaseExceptionMixin(Exception):
1112
code: int
1213

13-
def __init__(self, *, msg: str = None, data: Any = None):
14+
def __init__(self, *, msg: str = None, data: Any = None, background: BackgroundTask | None = None):
1415
self.msg = msg
1516
self.data = data
17+
# The original background task: https://www.starlette.io/background/
18+
self.background = background
1619

1720

1821
class HTTPError(HTTPException):
@@ -21,51 +24,53 @@ def __init__(self, *, code: int, msg: Any = None, headers: dict[str, Any] | None
2124

2225

2326
class CustomError(BaseExceptionMixin):
24-
def __init__(self, *, error: CustomCode, data: Any = None):
27+
def __init__(self, *, error: CustomCode, data: Any = None, background: BackgroundTask | None = None):
2528
self.code = error.code
26-
super().__init__(msg=error.msg, data=data)
29+
super().__init__(msg=error.msg, data=data, background=background)
2730

2831

2932
class RequestError(BaseExceptionMixin):
3033
code = 400
3134

32-
def __init__(self, *, msg: str = 'Bad Request', data: Any = None):
33-
super().__init__(msg=msg, data=data)
35+
def __init__(self, *, msg: str = 'Bad Request', data: Any = None, background: BackgroundTask | None = None):
36+
super().__init__(msg=msg, data=data, background=background)
3437

3538

3639
class ForbiddenError(BaseExceptionMixin):
3740
code = 403
3841

39-
def __init__(self, *, msg: str = 'Forbidden', data: Any = None):
40-
super().__init__(msg=msg, data=data)
42+
def __init__(self, *, msg: str = 'Forbidden', data: Any = None, background: BackgroundTask | None = None):
43+
super().__init__(msg=msg, data=data, background=background)
4144

4245

4346
class NotFoundError(BaseExceptionMixin):
4447
code = 404
4548

46-
def __init__(self, *, msg: str = 'Not Found', data: Any = None):
47-
super().__init__(msg=msg, data=data)
49+
def __init__(self, *, msg: str = 'Not Found', data: Any = None, background: BackgroundTask | None = None):
50+
super().__init__(msg=msg, data=data, background=background)
4851

4952

5053
class ServerError(BaseExceptionMixin):
5154
code = 500
5255

53-
def __init__(self, *, msg: str = 'Internal Server Error', data: Any = None):
54-
super().__init__(msg=msg, data=data)
56+
def __init__(
57+
self, *, msg: str = 'Internal Server Error', data: Any = None, background: BackgroundTask | None = None
58+
):
59+
super().__init__(msg=msg, data=data, background=background)
5560

5661

5762
class GatewayError(BaseExceptionMixin):
5863
code = 502
5964

60-
def __init__(self, *, msg: str = 'Bad Gateway', data: Any = None):
61-
super().__init__(msg=msg, data=data)
65+
def __init__(self, *, msg: str = 'Bad Gateway', data: Any = None, background: BackgroundTask | None = None):
66+
super().__init__(msg=msg, data=data, background=background)
6267

6368

6469
class AuthorizationError(BaseExceptionMixin):
6570
code = 401
6671

67-
def __init__(self, *, msg: str = 'Permission denied', data: Any = None):
68-
super().__init__(msg=msg, data=data)
72+
def __init__(self, *, msg: str = 'Permission denied', data: Any = None, background: BackgroundTask | None = None):
73+
super().__init__(msg=msg, data=data, background=background)
6974

7075

7176
class TokenError(HTTPError):

backend/app/common/exception/exception_handler.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,14 @@ def all_exception_handler(request: Request, exc: Exception):
104104
return JSONResponse(
105105
status_code=_get_exception_code(exc.code),
106106
content=response_base.fail(code=exc.code, msg=str(exc.msg), data=exc.data if exc.data else None),
107+
background=exc.background,
107108
)
108109

109110
else:
110-
import traceback
111-
112-
log.exception(traceback.format_exc())
111+
log.error(exc)
113112
return JSONResponse(
114113
status_code=500,
115-
content=response_base.fail(code=500, msg=traceback.format_exc())
114+
content=response_base.fail(code=500, msg=str(exc))
116115
if settings.ENVIRONMENT == 'dev'
117116
else response_base.fail(code=500, msg='Internal Server Error'),
118117
)

backend/app/services/auth_service.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
from fastapi import Request
77
from fastapi.security import OAuth2PasswordRequestForm
88
from pydantic.datetime_parse import parse_datetime
9-
from starlette.background import BackgroundTasks
9+
from starlette.background import BackgroundTasks, BackgroundTask
1010

1111
from backend.app.common import jwt
12+
from backend.app.common.enums import LoginLogStatus
1213
from backend.app.common.exception import errors
1314
from backend.app.common.jwt import get_token
1415
from backend.app.common.redis import redis_client
@@ -62,19 +63,31 @@ async def login(self, *, request: Request, obj: Auth, background_tasks: Backgrou
6263
refresh_token, refresh_token_expire_time = await jwt.create_refresh_token(
6364
str(user.id), access_token_expire_time, role_ids=user_role_ids, multi_login=user.is_multi_login
6465
)
65-
login_logs_params = dict(
66-
db=db, request=request, user=user, login_time=self.login_time, status=1, msg='登录成功'
67-
)
6866
except errors.NotFoundError as e:
6967
raise errors.NotFoundError(msg=e.msg)
7068
except errors.AuthorizationError as e:
71-
login_logs_params.update({'status': 0, 'msg': e.msg})
72-
background_tasks.add_task(LoginLogService.create, **login_logs_params)
73-
raise errors.AuthorizationError(msg=e.msg)
69+
err_log_info = dict(
70+
db=db,
71+
request=request,
72+
user=current_user,
73+
login_time=self.login_time,
74+
status=LoginLogStatus.fail,
75+
msg=e.msg,
76+
)
77+
task = BackgroundTask(LoginLogService.create, **err_log_info)
78+
raise errors.AuthorizationError(msg=e.msg, background=task)
7479
except Exception as e:
7580
raise e
7681
else:
77-
background_tasks.add_task(LoginLogService.create, **login_logs_params)
82+
log_info = dict(
83+
db=db,
84+
request=request,
85+
user=user,
86+
login_time=self.login_time,
87+
status=LoginLogStatus.success,
88+
msg='登录成功',
89+
)
90+
background_tasks.add_task(LoginLogService.create, **log_info)
7891
return access_token, refresh_token, access_token_expire_time, refresh_token_expire_time, user
7992

8093
@staticmethod

backend/app/services/login_log_service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ async def create(
4949
)
5050
await LoginLogDao.create(db, obj_in)
5151
except Exception as e:
52-
log.error(f'登录日志创建失败: {e}')
52+
log.exception(f'登录日志创建失败: {e}')
5353

5454
@staticmethod
5555
async def delete(pk: list[int]) -> int:

0 commit comments

Comments
 (0)