Сегодня расскажу про реальный кейс в разработке, который не тянет на выступление на конференции, но вполне сгодится для канала. Для описания буду использовать фреймворк S.T.A.R (Situation, Task, Action, Result).
Situation
Как вы все наверное слышали, компания Notion ушла из РФ. На тот момент все существующие аналоги работали очень плохо. А главное, не работал экспорт данных в эти самые аналоги. Notion великодушно предоставил возможность экспортировать данные в виде html файлов 😢
Многие использовали Notion как площадку для организации онлайн курсов. Так случилось, что один известный UX дизайнер Илона тоже использовала Notion для своего курса. Тут ее обзор на альтернативы Notion в момент ухода. Поэтому от Илоны поступило распоряжение, что-нибудь придумать, ведь я же программист😎
Итого, мы имеем пачку html файлов, организованных в странную структуру папок, которые ссылаются друг на друга. Там же где-то внутри находятся все медиа. И если открыть корневой html в браузере, это даже работает. Но нам нужно давать доступ до курса только тем, кто заплатил за него.
Task
что-нибудь придумать Организовать доступ до html файлов для тех, кто оплатил курс
Action
Понимая, что дело пахнет веб программированием, я сразу начал смотреть, а че там по хостингам. Будучи откровенным жадюгой, я решил, что не намерен платить гигантские косты за раздачу html 40 людям💰
Традиционно, самый дешевым способом захостить свой код являются клауд функции, где ты платишь только за вычисления. Однако, как только ты выходишь за пределы вычислений, там с тебя 3 шкуры сдерут. Кроме того, непонятно, на сколько перфоманс клауд функций позволяет быстро отдавать статику. Вдруг там будут затупы на старте. Поэтому сразу отказался от этого.
Принял решение, что сниму самый дешевый VPS и захостю все там. И это будут шикарные 1 CPU (3+ Ghz), 1 Gb RAM, 10 GB NVMe за 7 рублей в день. Обратите внимание, что на данном железе должно крутиться не только само приложение, но и ubuntu вместе с бд.
Кстати про бд, я решил не рисковать и не связываться с записью данных в файлик или sqlite, а сразу использовать нормальную бд MySQL. Почему так? дело в том, что помимо MySQL на этом же сервере можно развернуть phpmyadmin (pma) - и вот мы имеем админку для бедных из коробки! И в будущем эти 300 мб ОЗУ полностью оправдали себя.
Ну и теперь про само приложение. Как я уже сказал, нам нужно отдавать статику. Но часть этой статики должна быть прикрыта аутентификацией, а часть должна оставать в свободном доступе. Я сразу отмел всякие пхп и питоны, потому что, извините меня, но поднимать ларавель на отдачу каждого файлика - это никакой оперативы не напасешься.
Из технологий, с которыми я более менее знаком остались nodejs и golang. Поскольку, в день выбора технологии я был в адеквате, то победил golang 🤡 А если серьезно, то когда в nodejs научится не терять коннекшн к бд, тогда и поговорим.
Деплой было решено делать с помощью контейнеризации и такого великолепного инструмента, как docker compose. В итоге весь сетап представляет собой 4 контейнера: MySQL, pma, nginx и само приложение на golang. Nginx отвечал за ssl сертификаты.
Result
Итого, буквально из говна и палок в кратчайшие сроки было изготовлено решение, которое позволило "заказчику" провести очередной поток Пояснительного курса. Более того, данное решение получилось захостить на клубне картошки 🥔
Но это было только начало. Аппетиты клиента росли, и вскоре появились новые тебования 😱 Но об этом я расскажу в следующей части, которая будет больше про бизнес и про то, как может эволюционировать такой продукт
Situation
Как вы все наверное слышали, компания Notion ушла из РФ. На тот момент все существующие аналоги работали очень плохо. А главное, не работал экспорт данных в эти самые аналоги. Notion великодушно предоставил возможность экспортировать данные в виде html файлов 😢
Многие использовали Notion как площадку для организации онлайн курсов. Так случилось, что один известный UX дизайнер Илона тоже использовала Notion для своего курса. Тут ее обзор на альтернативы Notion в момент ухода. Поэтому от Илоны поступило распоряжение, что-нибудь придумать, ведь я же программист😎
Итого, мы имеем пачку html файлов, организованных в странную структуру папок, которые ссылаются друг на друга. Там же где-то внутри находятся все медиа. И если открыть корневой html в браузере, это даже работает. Но нам нужно давать доступ до курса только тем, кто заплатил за него.
Task
Action
Понимая, что дело пахнет веб программированием, я сразу начал смотреть, а че там по хостингам. Будучи откровенным жадюгой, я решил, что не намерен платить гигантские косты за раздачу html 40 людям💰
Традиционно, самый дешевым способом захостить свой код являются клауд функции, где ты платишь только за вычисления. Однако, как только ты выходишь за пределы вычислений, там с тебя 3 шкуры сдерут. Кроме того, непонятно, на сколько перфоманс клауд функций позволяет быстро отдавать статику. Вдруг там будут затупы на старте. Поэтому сразу отказался от этого.
Принял решение, что сниму самый дешевый VPS и захостю все там. И это будут шикарные 1 CPU (3+ Ghz), 1 Gb RAM, 10 GB NVMe за 7 рублей в день. Обратите внимание, что на данном железе должно крутиться не только само приложение, но и ubuntu вместе с бд.
Кстати про бд, я решил не рисковать и не связываться с записью данных в файлик или sqlite, а сразу использовать нормальную бд MySQL. Почему так? дело в том, что помимо MySQL на этом же сервере можно развернуть phpmyadmin (pma) - и вот мы имеем админку для бедных из коробки! И в будущем эти 300 мб ОЗУ полностью оправдали себя.
Ну и теперь про само приложение. Как я уже сказал, нам нужно отдавать статику. Но часть этой статики должна быть прикрыта аутентификацией, а часть должна оставать в свободном доступе. Я сразу отмел всякие пхп и питоны, потому что, извините меня, но поднимать ларавель на отдачу каждого файлика - это никакой оперативы не напасешься.
Из технологий, с которыми я более менее знаком остались nodejs и golang. Поскольку, в день выбора технологии я был в адеквате, то победил golang 🤡 А если серьезно, то когда в nodejs научится не терять коннекшн к бд, тогда и поговорим.
Деплой было решено делать с помощью контейнеризации и такого великолепного инструмента, как docker compose. В итоге весь сетап представляет собой 4 контейнера: MySQL, pma, nginx и само приложение на golang. Nginx отвечал за ssl сертификаты.
Result
Итого, буквально из говна и палок в кратчайшие сроки было изготовлено решение, которое позволило "заказчику" провести очередной поток Пояснительного курса. Более того, данное решение получилось захостить на клубне картошки 🥔
Но это было только начало. Аппетиты клиента росли, и вскоре появились новые тебования 😱 Но об этом я расскажу в следующей части, которая будет больше про бизнес и про то, как может эволюционировать такой продукт
😁5👏2🙉1
⚠️И сразу в догонку поясню, что пост выше надо воспринимать с некоторой долей юмора и обязательно в контексте задачи. Это не про "бест практисес". Хостить базу данных на том же сервере, что и ваше приложение, скорее нельзя, чем можно. Если вы так делаете, то вы должны отдавать себе отчет обо всех рисках, которые вы несете в этом случае!
👍2🐳1🌚1
https://github.com/ariga/atlas-provider-gorm - пакет для языка golang, позволяющий декларативно описывать миграции для gorm. У пакета 60+ звезд на гитхабе. А https://github.com/readyrevena/atlas-provider-gorm - это форк пакета atlas-provider с внедренным вредоносным кодом. У форка 120+ звезд на гитхабе. Если сильно поторопиться, то можно с радостью внедрить в свой проект уязвимость.
К чему я это все говорю. Проблемы с безопасностью на крупных платформах вроде гитхаба никуда не делись. И топовым фактором, понижающим безопасность, был и остается человеческий. Даже в этом случае, когда уязвимость программная, ее внедрение целиком и полностью зависит от внимательности разработчика.
Поэтому, прежде, чем тащить очередной пакет себе в проект стоит обратить внимание на следующие моменты:
* проекты, у которых единицы звезд на гитхабе - это вообще кот в мешке в плане безопасности и функционала
* проекты, у которых десятки звезд на гитхабе - это кот в мешке, но поменьше при условии, что вы чекнули следующие 2 пункта
* проверяем issues у репозитория, смотрим, живой или не живой проект. это полезно не только в плане безопасности, но и для понимания потенциальных проблем с функционалом
* смотрим, кто эти звезды ставит. если видим, что там преимущественно аккаунты, созданные пару месяцев назад - сразу бан
Короче говоря, безопасность - это серьезное дерьмо. Если вы нашли пакет, который позволяет вам быстро решить очередную вашу проблему, но у него меньше нескольких сотен звезд, стоит подумать о том, чтоб вместо внедрения очередной зависимости тупо скопировать оттуда код, который решает вашу проблему. Единственное, нужно убедиться, что лицензия пакета позволяет это сделать (MIT, apache-2.0, BSD это 👍, а вот gpl - вирусное дерьмо). Я так делал много раз, и все восхищались на ревью, какой же классный код я написал 🤡
Кстати говоря, на этой неделе я буквально решал подобную дилемму. Мне нужно было оформить логи в json в формате для нашего нового сервиса, который мы пишем на python. Офтопом можно отметить, что эта задача должна быть уже решена для любых популярных технологий. Ведь многие системы для сбора логов (например, ELK) принимают логи именно в формате json. Однако python продолжает неприятно удивлять. Потому что библиотека https://github.com/nhairs/python-json-logger, которая решает данную проблему, имеет всего 90+ звезд. И вот я сидел и думал полдня, тащить мне ее в зависимости или самому написать. В итоге я решил тащить. Но к счастью потом выяснилось, что мне все таки не нужен json в логах, и я с облегчением убрал эту зависимость 😌
К чему я это все говорю. Проблемы с безопасностью на крупных платформах вроде гитхаба никуда не делись. И топовым фактором, понижающим безопасность, был и остается человеческий. Даже в этом случае, когда уязвимость программная, ее внедрение целиком и полностью зависит от внимательности разработчика.
Поэтому, прежде, чем тащить очередной пакет себе в проект стоит обратить внимание на следующие моменты:
* проекты, у которых единицы звезд на гитхабе - это вообще кот в мешке в плане безопасности и функционала
* проекты, у которых десятки звезд на гитхабе - это кот в мешке, но поменьше при условии, что вы чекнули следующие 2 пункта
* проверяем issues у репозитория, смотрим, живой или не живой проект. это полезно не только в плане безопасности, но и для понимания потенциальных проблем с функционалом
* смотрим, кто эти звезды ставит. если видим, что там преимущественно аккаунты, созданные пару месяцев назад - сразу бан
Короче говоря, безопасность - это серьезное дерьмо. Если вы нашли пакет, который позволяет вам быстро решить очередную вашу проблему, но у него меньше нескольких сотен звезд, стоит подумать о том, чтоб вместо внедрения очередной зависимости тупо скопировать оттуда код, который решает вашу проблему. Единственное, нужно убедиться, что лицензия пакета позволяет это сделать (MIT, apache-2.0, BSD это 👍, а вот gpl - вирусное дерьмо). Я так делал много раз, и все восхищались на ревью, какой же классный код я написал 🤡
Кстати говоря, на этой неделе я буквально решал подобную дилемму. Мне нужно было оформить логи в json в формате для нашего нового сервиса, который мы пишем на python. Офтопом можно отметить, что эта задача должна быть уже решена для любых популярных технологий. Ведь многие системы для сбора логов (например, ELK) принимают логи именно в формате json. Однако python продолжает неприятно удивлять. Потому что библиотека https://github.com/nhairs/python-json-logger, которая решает данную проблему, имеет всего 90+ звезд. И вот я сидел и думал полдня, тащить мне ее в зависимости или самому написать. В итоге я решил тащить. Но к счастью потом выяснилось, что мне все таки не нужен json в логах, и я с облегчением убрал эту зависимость 😌
❤4😁1🐳1
Продолжаю изучать python, и рассказывать вам о своих успехах. Сегодня поговорим про туллинг, а именно про code quality tools.
Вот моя выжимка из кучи статей в интернете и чатгпт
* black - форматтер кода, есть интеграция с pycharm
* pylint - линтер общего назначения
* mypy - линтер и статический анализатор, отвечает за проверку типов при использовании аннотаций типов
И все вроде бы хорошо. Интегрировался с github actions, пофиксил ошибки, код стал чище и красивее. Но у меня с питоном всегда приколюхи находятся😏
К black нет никаких претензий. Он работает как крутяшка, все форматирует сам 😊Кароч, по красоте.
А вот с pylint у меня будет серьезный разговор. Я не понимаю, как линтер может существовать без опции --fix. У меня кода немного, что-то около 10 файлов по паре сотен строк кода. Но когда я запустил pylint первый раз, я просто охерел. Там было что-то около 100+ ошибок. И это после того, как black часть из них пофиксил.
Ну вот не понимаю, почему я должен вручную импорты в определенном порядке расставлять. Или почему я должен вручную менять f-нотацию на lazy интерполяцию (это которая с "%") в эксепшнах. Уж такие то вещи можно автоматизировать в 2025! Ух, помню, как я тогда выбесился, когда это все фиксил 🤬 Просто пиздосий.
Вот реально, все ругают php, типа всратый язык, и вообще, он уже давно умер. Но я вам ответственно заявляю, что в плане code quality тулинга ни один язык и близко не стоит рядом. Ну ладно, не будем пинать живой труп. Но в том же js/ts все работает замечательно. Да даже в golang ихний линтер имеет опцию --fix, и че то там пытается пофиксить, а компилятор так вообще сам форматирует код.
Понятно, что линтеры не все могут сами исправить (хотя в случае с пхп, кажется, что все), но че то в питоне совсем уж все плохо с этим 🤬
Ух! Ладно-ладно, может я чего-то не знаю про python, может я че-то упустил. Может надо было попробовать еще поставить другие форматтеры, типа autopep8 или flack8. Но че то по описанию, порядок импортов они не фиксят.
Но скажите мне тогда пожалуйста, какого рожна pylint такой медленный! напоминаю, у меня 10 файлов, по 200 - 500 строк кода всего лишь. И запуск pylint занимает 8 секунд на моем macbook pro с m1. 8 секунд!!! Что он там делает столько??? Понимаю, что звучу щас непрофессионально. Может надо сесть, поковыряться, разобраться, как настоящий тру программер. Но мне некогда этим заниматься, я хочу фичи для бизнеса делать.
Короче, вот вам идея для опенсорс проекта на питоне: делаем аналог rector. Не благодарите.
P.S. про mypy позже напишу, но там не так все ярко
Вот моя выжимка из кучи статей в интернете и чатгпт
* black - форматтер кода, есть интеграция с pycharm
* pylint - линтер общего назначения
* mypy - линтер и статический анализатор, отвечает за проверку типов при использовании аннотаций типов
И все вроде бы хорошо. Интегрировался с github actions, пофиксил ошибки, код стал чище и красивее. Но у меня с питоном всегда приколюхи находятся😏
К black нет никаких претензий. Он работает как крутяшка, все форматирует сам 😊Кароч, по красоте.
А вот с pylint у меня будет серьезный разговор. Я не понимаю, как линтер может существовать без опции --fix. У меня кода немного, что-то около 10 файлов по паре сотен строк кода. Но когда я запустил pylint первый раз, я просто охерел. Там было что-то около 100+ ошибок. И это после того, как black часть из них пофиксил.
Ну вот не понимаю, почему я должен вручную импорты в определенном порядке расставлять. Или почему я должен вручную менять f-нотацию на lazy интерполяцию (это которая с "%") в эксепшнах. Уж такие то вещи можно автоматизировать в 2025! Ух, помню, как я тогда выбесился, когда это все фиксил 🤬 Просто пиздосий.
Вот реально, все ругают php, типа всратый язык, и вообще, он уже давно умер. Но я вам ответственно заявляю, что в плане code quality тулинга ни один язык и близко не стоит рядом. Ну ладно, не будем пинать живой труп. Но в том же js/ts все работает замечательно. Да даже в golang ихний линтер имеет опцию --fix, и че то там пытается пофиксить, а компилятор так вообще сам форматирует код.
Понятно, что линтеры не все могут сами исправить (хотя в случае с пхп, кажется, что все), но че то в питоне совсем уж все плохо с этим 🤬
Ух! Ладно-ладно, может я чего-то не знаю про python, может я че-то упустил. Может надо было попробовать еще поставить другие форматтеры, типа autopep8 или flack8. Но че то по описанию, порядок импортов они не фиксят.
Но скажите мне тогда пожалуйста, какого рожна pylint такой медленный! напоминаю, у меня 10 файлов, по 200 - 500 строк кода всего лишь. И запуск pylint занимает 8 секунд на моем macbook pro с m1. 8 секунд!!! Что он там делает столько??? Понимаю, что звучу щас непрофессионально. Может надо сесть, поковыряться, разобраться, как настоящий тру программер. Но мне некогда этим заниматься, я хочу фичи для бизнеса делать.
Короче, вот вам идея для опенсорс проекта на питоне: делаем аналог rector. Не благодарите.
P.S. про mypy позже напишу, но там не так все ярко
Я рад сообщить, что решил часть своего контента вынести за пределы телеги. Поэтому завел свой микробложик https://nervprog.dev (да-да, я зарегал домен 😊), и планирую туда писать миддл и лонг риды. Причина проста - телега не очень подходит для длинных постов, да еще и с кодом. Посмотрим, как оно пойдет (и пойдет ли).
В планах - прикрутить RSS и делать варианты статей на английском с помощью чатгпт. Пока что написал небольшую пробную статейку Как правильно подключиться к базе данных в Fastapi. Статья будто бы для питонистов, но на самом деле, она больше проглобальные переменные поиск подходов. Напишите в комментах, стоит или нет такое пытаться на medium.com / dev.to / vc.ru публиковать или надо че-то посерьезнее?
P.S. Стоит зайти хотя бы раз, чтоб оценить, какой классный дизайн я выбрал 🤩
В планах - прикрутить RSS и делать варианты статей на английском с помощью чатгпт. Пока что написал небольшую пробную статейку Как правильно подключиться к базе данных в Fastapi. Статья будто бы для питонистов, но на самом деле, она больше про
P.S. Стоит зайти хотя бы раз, чтоб оценить, какой классный дизайн я выбрал 🤩
🔥8🍾2❤1🗿1
Обработка ошибок в языках программирования - это вопрос дискусионный. Какого-то консенсуса, как делать правильно, здесь нет по сей день. Где-то язык не предоставляет никаких механизмов для решения этой задачи, отдавая этот вопрос полностью на откуп программистам (привет Си), где-то ошибки - это почти обычные значения, которые возвращаются вместе с результатом выполнения функции (привет golang). Однако наибольшее распространение получил механизм исключений, представленный в таких языках как java, c#, javascript, php и др. Этот подход имеет свои недостатки, но этот пост не о них.
Этот пост об исключениях в python 🥲 Да, в python есть исключения. Есть свой блок try -catch except - finally. И эти знакомые слова могут создать иллюзию похожести. Но это обманчиво.
Первое отличие, которое бросается в глаза, это что стэк трейс в питоне "перевернут". В логах даже всегда есть строчка перед ним Traceback (most recent call last), чтоб вы не забывали. Но это ладно.
Я привык к тому, что exception - это иммутабельная структура данных. То есть, если я где то пишу throw new Exception(), то в этот момент в него помещается вся информация об ошибке и стэк трейс. И дальше уже не важно, что я там буду делать с ним - вся инфа зафиксирована, стектрейс никак не поменяется.
А в питоне? А в питоне есть офигительная возможность, добавлять заметки к эксепшнам 😂
ладно-ладно, давайте посерьезке 🤓
Честно говоря, не знаю, как там это устроено под капотом, но поведение исключения мутабельное с точки зрения логирования стектрейса 😱 Рассмотрим пример
В этом случае в стек трейсе будет 3 записи: do_smth_deeper -> do_smth -> main. Логично? Логично!
Внесем мааааленькое изменение в наш код: используем именованный raise.
Стектрейс изменился, теперь там 4 записи do_smth_deeper -> do_smth -> do_smth (raise e) -> main. Появилась еще одна запись перед main, относящаяся к строчке raise e.
Еще одна трансформация:
соответственно стэк трейс будет do_smth_deeper -> do_smth_deeper (raise e) -> do_smth (raise e) -> do_smth -> main.
Получается, в python стэкрейс зависит от количества (простихоспади) ре-raise-ов на пути всплывания к логгеру! 🤡
И это еще не все. Но продолжение уже в следующем посте, шоб сильно не грузить и дать мозгу отдохнуть
Этот пост об исключениях в python 🥲 Да, в python есть исключения. Есть свой блок try -
Первое отличие, которое бросается в глаза, это что стэк трейс в питоне "перевернут". В логах даже всегда есть строчка перед ним Traceback (most recent call last), чтоб вы не забывали. Но это ладно.
Я привык к тому, что exception - это иммутабельная структура данных. То есть, если я где то пишу throw new Exception(), то в этот момент в него помещается вся информация об ошибке и стэк трейс. И дальше уже не важно, что я там буду делать с ним - вся инфа зафиксирована, стектрейс никак не поменяется.
А в питоне? А в питоне есть офигительная возможность, добавлять заметки к эксепшнам 😂
ладно-ладно, давайте посерьезке 🤓
Честно говоря, не знаю, как там это устроено под капотом, но поведение исключения мутабельное с точки зрения логирования стектрейса 😱 Рассмотрим пример
def main():
try:
do_smth()
except Exception:
logging.error("Uncaught exception", exc_info=True)
def do_smth():
try:
do_smth_deeper()
except Exception:
raise
def do_smth_deeper():
raise RuntimeError("deep error")
В этом случае в стек трейсе будет 3 записи: do_smth_deeper -> do_smth -> main. Логично? Логично!
Внесем мааааленькое изменение в наш код: используем именованный raise.
def do_smth():
try:
do_smth_deeper()
except Exception as e:
raise e
Стектрейс изменился, теперь там 4 записи do_smth_deeper -> do_smth -> do_smth (raise e) -> main. Появилась еще одна запись перед main, относящаяся к строчке raise e.
Еще одна трансформация:
def do_smth_deeper():
try:
raise RuntimeError("deep error")
except Exception as e:
raise e
соответственно стэк трейс будет do_smth_deeper -> do_smth_deeper (raise e) -> do_smth (raise e) -> do_smth -> main.
Получается, в python стэкрейс зависит от количества (простихоспади) ре-raise-ов на пути всплывания к логгеру! 🤡
И это еще не все. Но продолжение уже в следующем посте, шоб сильно не грузить и дать мозгу отдохнуть
👍3👌2❤1
Ну шо? Отдохнули?
Тада давайте вам небольшой интерактивчик.
Я немного модифицировал код из предыдущего поста.
Я просто сохранил "deep error" в переменную, чтоб "воспользоваться" ей позднее.
Тада давайте вам небольшой интерактивчик.
Я немного модифицировал код из предыдущего поста.
def main():
try:
do_smth()
except Exception:
logging.error("Uncaught exception", exc_info=True)
def do_smth():
deep_err = None
try:
do_smth_deeper()
except Exception as e:
deep_err = e
try:
raise RuntimeError("shallow error")
except Exception:
raise deep_err
def do_smth_deeper():
raise RuntimeError("deep error")
Я просто сохранил "deep error" в переменную, чтоб "воспользоваться" ей позднее.
Итак, все кто проголосовал, те проголосовали 🤓правильный ответ: будет показана инфа об обеих ошибках, причем сначала будет показана инфа о shallow error. А вот deep error будет помечена как ошибка, которая случилась во время обработки shallow error.
During handling of the above exception, another exception occurred
При этом сама ошибка в блоке except с логгером будет именно deep error, но в логах все выглядит так, будто именно shallow error основная ошибка 🤡
Я столкнулся с этим поведением, когда решил, что мне нужно отлавливать все исключения в fastapi в одном месте. Там же я решил и логировать исключения. Я написал middleware с try except - все как завещал Deepseek. Каково же было мое удивление, когда в логах обнаружил сначала каких-то два внутренних эксепшна fastapi, а только потом уже мой эксепшн. И это типа норма 🤷 А в логах образовалась гора ненужного мусора 😢
А к чему я это все говорю? К тому, что стандартизация и консенсус важны в разработке. Они формируют ожидания и привычки, которые экономят мыслетопливо при работе, позволяют быстрее учиться. Хороший пример здесь async - await. Эта конструкция работает схожим образом, что в js, что в c#, что в kotlin, что в python. Детали могут отличаться (Promise vs Deferred vs Future), но принцип один.
Исключения в python, на мой взгляд, ломают "консенсус" исключений в ЯП. python не предлагает принципиально отличающийся механизм обработки ошибок. Это все те же исключения. Но при этом реализация будто не соответствует ожиданиям. И приходится переучиваться, что в моем возрасте уже чревато перенапряжением 😢
During handling of the above exception, another exception occurred
При этом сама ошибка в блоке except с логгером будет именно deep error, но в логах все выглядит так, будто именно shallow error основная ошибка 🤡
Я столкнулся с этим поведением, когда решил, что мне нужно отлавливать все исключения в fastapi в одном месте. Там же я решил и логировать исключения. Я написал middleware с try except - все как завещал Deepseek. Каково же было мое удивление, когда в логах обнаружил сначала каких-то два внутренних эксепшна fastapi, а только потом уже мой эксепшн. И это типа норма 🤷 А в логах образовалась гора ненужного мусора 😢
А к чему я это все говорю? К тому, что стандартизация и консенсус важны в разработке. Они формируют ожидания и привычки, которые экономят мыслетопливо при работе, позволяют быстрее учиться. Хороший пример здесь async - await. Эта конструкция работает схожим образом, что в js, что в c#, что в kotlin, что в python. Детали могут отличаться (Promise vs Deferred vs Future), но принцип один.
Исключения в python, на мой взгляд, ломают "консенсус" исключений в ЯП. python не предлагает принципиально отличающийся механизм обработки ошибок. Это все те же исключения. Но при этом реализация будто не соответствует ожиданиям. И приходится переучиваться, что в моем возрасте уже чревато перенапряжением 😢
👍3👾1
Написал еще одну небольшую статейку об обработке ошибок в Fastapi 😊
Стоит отметить, что подобные задачи возникают в других языках и микрофреймворках. Например, такой же вопрос можно поднять для expressjs, fastify, slim, open swoole и прочих. И обычно все решается либо кастомизацией обработчика, либо написанием middleware. Как и в Fastapi. А ответ чаще всего прямо написан в документации к фреймворкам.
Но отличие состоит в том, что вfastapi этого нет в документации python мы можем влиять на размер бэктрейса в логах. А раз так, то почему бы нам этим не воспользоваться. И я считаю это микро-концептуальным моментом 🤓 Можно бомбить на то, что бэктрейс в python ведет себя, как тварь. А можно обернуть это себе в пользу, почистив логи от ненужного мусора ☝️
Штош. На этом я пока что заканчиваю сезон python на канале. Надеюсь, было интересно 😘
Стоит отметить, что подобные задачи возникают в других языках и микрофреймворках. Например, такой же вопрос можно поднять для expressjs, fastify, slim, open swoole и прочих. И обычно все решается либо кастомизацией обработчика, либо написанием middleware. Как и в Fastapi. А ответ чаще всего прямо написан в документации к фреймворкам.
Но отличие состоит в том, что в
Штош. На этом я пока что заканчиваю сезон python на канале. Надеюсь, было интересно 😘
Telegram
Нервный программист
Обработка ошибок в языках программирования - это вопрос дискусионный. Какого-то консенсуса, как делать правильно, здесь нет по сей день. Где-то язык не предоставляет никаких механизмов для решения этой задачи, отдавая этот вопрос полностью на откуп программистам…
👍5❤1
Так блэт! 🤬
Во-первых, я потратил какое-то время для того, чтоб в принципе решить проблему, которую я в статье описал. Я гуглил, спрашивал Deepseek и ChatGPT, эксперементировал. Потратил на эту задачу целый рабочий день, потому что нихера не было понятно, и результат не нравился!
Во-вторых, я несколько дней писал статью! И пока я писал, я гуглил, спрашивал Deepseek и ChatGPT,экскрементировал эксперементировал!
И вот только что я чисто случайно!!! наткнулся на решение проблемы в документации. Я вообще попал на эту страницу по другому поводу. Я бы даже сказал, я не должен был туда попадать. Потому что эта страница находится в разделе How To - Recipes. А называется она Custom Request and APIRoute class.
Ну вот нахера бы мне вообще Custom Request писать, скажите пожалуйста. У меня обычная апишка. Смысл вообще мне туда заглядывать! И находится эта страница в какой-то жепе, уже после основной документации. Явно же факультативное чтиво! 😤
Но вот именно Custom APIRoute решает все проблемы! там даже сука пример есть с отловом ошибки, но он опять же в другом контексте показан. И написано рядом "лучше пользоваться exception hadnlerами, это чисто демонстрация".
Я вам клянусь, интернет не в курсе этого способа. Всех устраивает, что логи полны говна.
Буду править статью, но выбесився конечно😡 С другой стороны, раз никто об этом еще не писал, в этом может быть больше ценности. Главное все проверить еще раз, чтоб снова не обосраться!
Во-первых, я потратил какое-то время для того, чтоб в принципе решить проблему, которую я в статье описал. Я гуглил, спрашивал Deepseek и ChatGPT, эксперементировал. Потратил на эту задачу целый рабочий день, потому что нихера не было понятно, и результат не нравился!
Во-вторых, я несколько дней писал статью! И пока я писал, я гуглил, спрашивал Deepseek и ChatGPT,
И вот только что я чисто случайно!!! наткнулся на решение проблемы в документации. Я вообще попал на эту страницу по другому поводу. Я бы даже сказал, я не должен был туда попадать. Потому что эта страница находится в разделе How To - Recipes. А называется она Custom Request and APIRoute class.
Ну вот нахера бы мне вообще Custom Request писать, скажите пожалуйста. У меня обычная апишка. Смысл вообще мне туда заглядывать! И находится эта страница в какой-то жепе, уже после основной документации. Явно же факультативное чтиво! 😤
Но вот именно Custom APIRoute решает все проблемы! там даже сука пример есть с отловом ошибки, но он опять же в другом контексте показан. И написано рядом "лучше пользоваться exception hadnlerами, это чисто демонстрация".
Я вам клянусь, интернет не в курсе этого способа. Всех устраивает, что логи полны говна.
Буду править статью, но выбесився конечно😡 С другой стороны, раз никто об этом еще не писал, в этом может быть больше ценности. Главное все проверить еще раз, чтоб снова не обосраться!
Tiangolo
Custom Request and APIRoute class - FastAPI
FastAPI framework, high performance, easy to learn, fast to code, ready for production
😁3❤2⚡1