@m-kicherov

Какой паттерн использовать для обработки исключений в api?

Добрый день, делаю api на python которое должно отдавать pdf, получилось что нужно проверить кучу условий перед этим, сформирована пдф или еще формируется, файл не найден и выглядит это все не очень красиво, осознаю что сделал спагетти.

Подскажите как можно переделать метод get_pdf ближе к pythonic way, посоветуйте какие нибудь паттерны?

class TaskControl(BaseControl):
    tickets = TicketQueries
    task_sql = PrintTaskQueries
    sub_task_control = SubTaskControl()
    storage = Storage()

    async def objects(self, limit: int = DEFAULT_LIMIT, offset: int = DEFAULT_OFFSET, **kwargs) -> t.Dict[str, t.Any]:
        count = await self.task_sql().count(**kwargs)
        return {
            'pages_count': count // limit + (1 if count % limit > 0 else 0),
            'page': offset // limit + 1,
            'tasks': [task.to_dict() for task in await self.task_sql().objects(limit=limit, offset=offset, **kwargs)]
        }

    async def create(self, city: int, courier: int, period: date, **kwargs) -> PrintTask:
        if not (tickets := await self.tickets().objects(period, city, courier, **kwargs)):
            raise TaskCreateException(f'Не найдены квитанции в периоде {period} для город:{city}, курьер:{courier} параметры {kwargs}')
        task = await self.task_sql().insert(PrintTask.create(period, conditions={'city': city, 'courier': courier, **kwargs}))
        return task.set_subtasks(await self.sub_task_control.create(tickets, task))

    async def get(self, oid: int) -> PrintTask:
        try:
            task = await self.task_sql().get(oid)
        except PgNotFoundException as ex:
            raise TaskNotFoundException(f'Задача {oid} не найдена') from ex
        return task.set_subtasks(await self.sub_task_control.objects(print_task=oid))

    async def change_status(self, oid: int, status: int) -> PrintTask:
        task = await self.get(oid)
        if status not in TaskStatus.__members__.values():
            raise ValidationException('Статус не поддерживается')
        return (await self.task_sql().set_status(task.oid, status)).set_subtasks(await self.sub_task_control.objects(print_task=oid))

    async def get_pdf(self, oid: int, sub_task: int) -> File:
        task = await self.get(oid)
        if sub_task not in task:
            raise TaskNotFoundException(f'Задача {oid} не содержит подзадачу {sub_task}')
        if task[sub_task].status != SubTaskStatus.SUCCESS.value:
            raise TaskNotReadyException(f'Подзадача {sub_task} не готова')
        try:
            return File(
                self.storage.get(f'{task[sub_task].uuid}.pdf'),
                f'{task.display_courier} - {task[sub_task].display_street}',
                EXTENSION.PDF
            )
        except StorageNotFoundException as ex:
            raise FileNotFoundException(f'Файл {task[sub_task].uuid}.pdf не найден') from ex
  • Вопрос задан
  • 84 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы