WIP: Better exception handling

This commit is contained in:
Profitroll 2023-02-16 15:04:28 +01:00
parent 80897dd79c
commit e2633a01e5
3 changed files with 28 additions and 12 deletions

View File

@ -54,3 +54,6 @@ class SearchResultsPhoto(BaseModel):
class SearchResultsVideo(BaseModel): class SearchResultsVideo(BaseModel):
results: List[VideoSearch] results: List[VideoSearch]
next_page: Union[str, None] next_page: Union[str, None]
class EmailConfirmed(BaseModel):
detail: str

View File

@ -1,66 +1,68 @@
from fastapi import Request
from fastapi.responses import UJSONResponse
from modules.app import app from modules.app import app
from classes.exceptions import * from classes.exceptions import *
from starlette.status import HTTP_400_BAD_REQUEST, HTTP_401_UNAUTHORIZED, HTTP_404_NOT_FOUND, HTTP_406_NOT_ACCEPTABLE, HTTP_409_CONFLICT from starlette.status import HTTP_400_BAD_REQUEST, HTTP_401_UNAUTHORIZED, HTTP_404_NOT_FOUND, HTTP_406_NOT_ACCEPTABLE, HTTP_409_CONFLICT
@app.exception_handler(AlbumNotFoundError) @app.exception_handler(AlbumNotFoundError)
async def album_not_found_exception_handler(request: Request, exc: AlbumNotFoundError): async def album_not_found_exception_handler(request: Request, exc: AlbumNotFoundError):
return JSONResponse( return UJSONResponse(
status_code=HTTP_404_NOT_FOUND, status_code=HTTP_404_NOT_FOUND,
content={"detail": f"Could not find album with id '{exc.id}'."}, content={"detail": f"Could not find album with id '{exc.id}'."},
) )
@app.exception_handler(AlbumAlreadyExistsError) @app.exception_handler(AlbumAlreadyExistsError)
async def album_already_exists_exception_handler(request: Request, exc: AlbumAlreadyExistsError): async def album_already_exists_exception_handler(request: Request, exc: AlbumAlreadyExistsError):
return JSONResponse( return UJSONResponse(
status_code=HTTP_409_CONFLICT, status_code=HTTP_409_CONFLICT,
content={"detail": f"Album with name '{exc.name}' already exists."}, content={"detail": f"Album with name '{exc.name}' already exists."},
) )
@app.exception_handler(AlbumIncorrectError) @app.exception_handler(AlbumIncorrectError)
async def album_incorrect_exception_handler(request: Request, exc: AlbumIncorrectError): async def album_incorrect_exception_handler(request: Request, exc: AlbumIncorrectError):
return JSONResponse( return UJSONResponse(
status_code=HTTP_406_NOT_ACCEPTABLE, status_code=HTTP_406_NOT_ACCEPTABLE,
content={"detail": f"Album {exc.place} invalid: {exc.error}"}, content={"detail": f"Album {exc.place} invalid: {exc.error}"},
) )
@app.exception_handler(PhotoNotFoundError) @app.exception_handler(PhotoNotFoundError)
async def photo_not_found_exception_handler(request: Request, exc: PhotoNotFoundError): async def photo_not_found_exception_handler(request: Request, exc: PhotoNotFoundError):
return JSONResponse( return UJSONResponse(
status_code=HTTP_404_NOT_FOUND, status_code=HTTP_404_NOT_FOUND,
content={"detail": f"Could not find photo with id '{exc.id}'."}, content={"detail": f"Could not find photo with id '{exc.id}'."},
) )
@app.exception_handler(SearchPageInvalidError) @app.exception_handler(SearchPageInvalidError)
async def search_page_invalid_exception_handler(request: Request, exc: SearchPageInvalidError): async def search_page_invalid_exception_handler(request: Request, exc: SearchPageInvalidError):
return JSONResponse( return UJSONResponse(
status_code=HTTP_400_BAD_REQUEST, status_code=HTTP_400_BAD_REQUEST,
content={"detail": "Parameters 'page' and 'page_size' must be greater or equal to 1."}, content={"detail": "Parameters 'page' and 'page_size' must be greater or equal to 1."},
) )
@app.exception_handler(SearchTokenInvalidError) @app.exception_handler(SearchTokenInvalidError)
async def search_token_invalid_exception_handler(request: Request, exc: SearchTokenInvalidError): async def search_token_invalid_exception_handler(request: Request, exc: SearchTokenInvalidError):
return JSONResponse( return UJSONResponse(
status_code=HTTP_401_UNAUTHORIZED, status_code=HTTP_401_UNAUTHORIZED,
content={"detail": "Parameters 'page' and 'page_size' must be greater or equal to 1."}, content={"detail": "Parameters 'page' and 'page_size' must be greater or equal to 1."},
) )
@app.exception_handler(UserEmailCodeInvalid) @app.exception_handler(UserEmailCodeInvalid)
async def user_email_code_invalid_exception_handler(request: Request, exc: UserEmailCodeInvalid): async def user_email_code_invalid_exception_handler(request: Request, exc: UserEmailCodeInvalid):
return JSONResponse( return UJSONResponse(
status_code=HTTP_400_BAD_REQUEST, status_code=HTTP_400_BAD_REQUEST,
content={"detail": "Confirmation code is invalid."}, content={"detail": "Confirmation code is invalid."},
) )
@app.exception_handler(UserAlreadyExists) @app.exception_handler(UserAlreadyExists)
async def user_already_exists_exception_handler(request: Request, exc: UserAlreadyExists): async def user_already_exists_exception_handler(request: Request, exc: UserAlreadyExists):
return JSONResponse( return UJSONResponse(
status_code=HTTP_409_CONFLICT, status_code=HTTP_409_CONFLICT,
content={"detail": "User with this username already exists."}, content={"detail": "User with this username already exists."},
) )
@app.exception_handler(UserCredentialsInvalid) @app.exception_handler(UserCredentialsInvalid)
async def user_credentials_invalid_exception_handler(request: Request, exc: UserCredentialsInvalid): async def user_credentials_invalid_exception_handler(request: Request, exc: UserCredentialsInvalid):
return JSONResponse( return UJSONResponse(
status_code=HTTP_401_UNAUTHORIZED, status_code=HTTP_401_UNAUTHORIZED,
content={"detail": "Invalid credentials."}, content={"detail": "Invalid credentials."},
) )

View File

@ -1,5 +1,6 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from classes.exceptions import UserAlreadyExists, UserCredentialsInvalid, UserEmailCodeInvalid from classes.exceptions import UserAlreadyExists, UserCredentialsInvalid, UserEmailCodeInvalid
from classes.models import EmailConfirmed
from modules.database import col_users, col_albums, col_photos, col_emails, col_videos, col_emails from modules.database import col_users, col_albums, col_photos, col_emails, col_videos, col_emails
from modules.app import app from modules.app import app
from modules.utils import configGet, logWrite from modules.utils import configGet, logWrite
@ -40,11 +41,21 @@ async def user_me(current_user: User = Depends(get_current_active_user)):
user_confirm_responses = { user_confirm_responses = {
200: {
"description": "Successful Response",
"content": {
"application/json": {
"example": {
"detail": configGet("email_confirmed", "messages")
}
}
}
},
400: UserEmailCodeInvalid().openapi 400: UserEmailCodeInvalid().openapi
} }
if configGet("registration_requires_confirmation") is True: if configGet("registration_requires_confirmation") is True:
@app.get("/users/{user}/confirm", responses=user_confirm_responses) @app.get("/users/{user}/confirm", response_class=UJSONResponse, response_model=EmailConfirmed, responses=user_confirm_responses)
@app.patch("/users/{user}/confirm", responses=user_confirm_responses) @app.patch("/users/{user}/confirm", response_class=UJSONResponse, response_model=EmailConfirmed, responses=user_confirm_responses)
async def user_confirm(user: str, code: str): async def user_confirm(user: str, code: str):
confirm_record = col_emails.find_one( {"user": user, "code": code, "used": False} ) confirm_record = col_emails.find_one( {"user": user, "code": code, "used": False} )
if confirm_record is None: if confirm_record is None: