diff --git a/print_service/base.py b/print_service/base.py index b600580..7df662f 100644 --- a/print_service/base.py +++ b/print_service/base.py @@ -15,3 +15,4 @@ class Config: class StatusResponseModel(Base): status: str message: str + ru: str diff --git a/print_service/routes/exc_handlers.py b/print_service/routes/exc_handlers.py index 63d286e..f10a38e 100644 --- a/print_service/routes/exc_handlers.py +++ b/print_service/routes/exc_handlers.py @@ -1,3 +1,4 @@ +import requests.models import starlette.requests from starlette.responses import JSONResponse @@ -22,33 +23,54 @@ UserNotFound, ) from print_service.routes.base import app +from print_service.settings import get_settings + + +settings = get_settings() @app.exception_handler(TooLargeSize) async def too_large_size(req: starlette.requests.Request, exc: TooLargeSize): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=413 + content=StatusResponseModel( + status="Error", + message=f"{exc}", + ru=f"Размер файла превышает максимально допустимый: {settings.MAX_SIZE}", + ).dict(), + status_code=413, ) @app.exception_handler(TooManyPages) async def too_many_pages(req: starlette.requests.Request, exc: TooManyPages): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=413 + content=StatusResponseModel( + status="Error", + message=f"{exc}", + ru=f"Количество запрошенных страниц превышает допустимое число: {settings.MAX_PAGE_COUNT}", + ).dict(), + status_code=413, ) @app.exception_handler(InvalidPageRequest) async def invalid_format(req: starlette.requests.Request, exc: TooManyPages): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=416 + content=StatusResponseModel( + status="Error", + message=f"{exc}", + ru="Количество запрошенных страниц превышает их количество в файле", + ).dict(), + status_code=416, ) @app.exception_handler(TerminalQRNotFound) async def terminal_not_found_by_qr(req: starlette.requests.Request, exc: TerminalQRNotFound): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"Terminal not found by QR").dict(), + content=StatusResponseModel( + status="Error", message="Terminal not found by QR", ru="QR-код не найден" + ).dict(), status_code=400, ) @@ -56,7 +78,9 @@ async def terminal_not_found_by_qr(req: starlette.requests.Request, exc: Termina @app.exception_handler(TerminalTokenNotFound) async def terminal_not_found_by_token(req: starlette.requests.Request, exc: TerminalTokenNotFound): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"Terminal not found by token").dict(), + content=StatusResponseModel( + status="Error", message="Terminal not found by token", ru="Токен не найден" + ).dict(), status_code=400, ) @@ -64,42 +88,63 @@ async def terminal_not_found_by_token(req: starlette.requests.Request, exc: Term @app.exception_handler(UserNotFound) async def user_not_found(req: starlette.requests.Request, exc: UserNotFound): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"User not found").dict(), status_code=404 + content=StatusResponseModel( + status="Error", message="User not found", ru="Пользователь не найден" + ).dict(), + status_code=404, ) @app.exception_handler(UnionStudentDuplicate) async def student_duplicate(req: starlette.requests.Request, exc: UnionStudentDuplicate): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=400 + content=StatusResponseModel( + status="Error", + message=f"{exc}", + ru="Один или более пользователей в списке не являются уникальными", + ).dict(), + status_code=400, ) @app.exception_handler(NotInUnion) async def not_in_union(req: starlette.requests.Request, exc: NotInUnion): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=403 + content=StatusResponseModel( + status="Error", + message=f"{exc}", + ru="Отсутствует членство в профсоюзе", + ).dict(), + status_code=403, ) @app.exception_handler(PINGenerateError) async def generate_error(req: starlette.requests.Request, exc: PINGenerateError): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=500 + content=StatusResponseModel( + status="Error", + message=f"{exc}", + ru="Ошибка генерации ПИН-кода", + ).dict(), + status_code=500, ) @app.exception_handler(FileIsNotReceived) async def file_not_received(req: starlette.requests.Request, exc: FileIsNotReceived): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=400 + content=StatusResponseModel(status="Error", message=f"{exc}", ru="Файл не получен").dict(), + status_code=400, ) @app.exception_handler(PINNotFound) async def pin_not_found(req: starlette.requests.Request, exc: PINNotFound): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"Pin {exc.pin} not found").dict(), + content=StatusResponseModel( + status="Error", message=f"Pin {exc.pin} not found", ru="ПИН не найден" + ).dict(), status_code=404, ) @@ -107,35 +152,47 @@ async def pin_not_found(req: starlette.requests.Request, exc: PINNotFound): @app.exception_handler(InvalidType) async def invalid_type(req: starlette.requests.Request, exc: InvalidType): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=415 + content=StatusResponseModel( + status="Error", + message=f"{exc}", + ru=f"Неподдерживаемый формат файла. Допустимые: {', '.join(settings.CONTENT_TYPES)}", + ).dict(), + status_code=415, ) @app.exception_handler(AlreadyUploaded) async def already_upload(req: starlette.requests.Request, exc: AlreadyUploaded): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=415 + content=StatusResponseModel(status="Error", message=f"{exc}", ru="Файл уже загружен").dict(), + status_code=415, ) @app.exception_handler(IsCorrupted) async def is_corrupted(req: starlette.requests.Request, exc: IsCorrupted): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=415 + content=StatusResponseModel(status="Error", message=f"{exc}", ru="Файл повреждён").dict(), + status_code=415, ) @app.exception_handler(UnprocessableFileInstance) async def unprocessable_file_instance(req: starlette.requests.Request, exc: UnprocessableFileInstance): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=422 + content=StatusResponseModel( + status="Error", message=f"{exc}", ru="Необрабатываемый экземпляр файла" + ).dict(), + status_code=422, ) @app.exception_handler(FileNotFound) async def file_not_found(req: starlette.requests.Request, exc: FileNotFound): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc.count} file(s) not found").dict(), + content=StatusResponseModel( + status="Error", message=f"{exc.count} file(s) not found", ru="Файл не найден" + ).dict(), status_code=404, ) @@ -143,5 +200,6 @@ async def file_not_found(req: starlette.requests.Request, exc: FileNotFound): @app.exception_handler(IsNotUploaded) async def not_uploaded(req: starlette.requests.Request, exc: IsNotUploaded): return JSONResponse( - content=StatusResponseModel(status="Error", message=f"{exc}").dict(), status_code=415 + content=StatusResponseModel(status="Error", message=f"{exc}", ru="Файл не загружен").dict(), + status_code=415, ) diff --git a/print_service/routes/file.py b/print_service/routes/file.py index b8208c5..36248f0 100644 --- a/print_service/routes/file.py +++ b/print_service/routes/file.py @@ -11,6 +11,7 @@ from pydantic import Field, validator from sqlalchemy import func, or_ +from print_service.base import StatusResponseModel from print_service.exceptions import ( AlreadyUploaded, FileIsNotReceived, @@ -100,7 +101,8 @@ class ReceiveOutput(BaseModel): @router.post( '', responses={ - 403: {'detail': 'User error'}, + 403: {'model': StatusResponseModel, 'detail': 'User error'}, + 500: {'model': StatusResponseModel, 'detail': 'PIN generate error'}, }, response_model=SendOutput, ) @@ -124,7 +126,7 @@ async def send(inp: SendInput, settings: Settings = Depends(get_settings)): try: pin = generate_pin(db.session) except RuntimeError: - raise PINGenerateError + raise PINGenerateError() filename = generate_filename(inp.filename) file_model = FileModel(pin=pin, file=filename) file_model.owner = user @@ -147,8 +149,11 @@ async def send(inp: SendInput, settings: Settings = Depends(get_settings)): @router.post( '/{pin:str}', responses={ - 404: {'detail': 'Pin not found'}, - 415: {'detail': 'File error'}, + 400: {'model': StatusResponseModel, 'detail': 'File is not received'}, + 404: {'model': StatusResponseModel, 'detail': 'Pin not found'}, + 415: {'model': StatusResponseModel, 'detail': 'File error'}, + 413: {'model': StatusResponseModel, 'detail': 'Too large file'}, + 416: {'model': StatusResponseModel, 'detail': 'Invalid page request'}, }, response_model=SendOutput, ) @@ -216,7 +221,9 @@ async def upload_file( @router.patch( '/{pin:str}', responses={ - 404: {'detail': 'Pin not found'}, + 404: {'model': StatusResponseModel, 'detail': 'Pin not found'}, + 413: {'model': StatusResponseModel, 'detail': 'Too many pages'}, + 416: {'model': StatusResponseModel, 'detail': 'Invalid page request'}, }, response_model=SendOutput, ) @@ -261,8 +268,9 @@ async def update_file_options( @router.get( '/{pin:str}', responses={ - 404: {'detail': 'Pin not found'}, - 415: {'detail': 'File error'}, + 404: {'model': StatusResponseModel, 'detail': 'Pin not found'}, + 415: {'model': StatusResponseModel, 'detail': 'File error'}, + 416: {'model': StatusResponseModel, 'detail': 'Invalid page request'}, }, response_model=ReceiveOutput, )