Какие ошибки могут возникнуть при получении пользователя по id и как их обработать
Что проверяют
Умеете ли вы разложить обработку ошибок по слоям и выбрать правильный HTTP-статус для каждого случая. Следом обычно спрашивают, где должно жить превращение исключения в ответ: в сервисе или в обработчике.
Как отвечать
Пройдите по пути запроса на примере FastAPI или Django:
- невалидный id: строка вместо числа, битый UUID. В FastAPI при аннотации
user_id: intэто ловится до вашего кода, клиент получает 422. В Django конвертер<int:user_id>не пропустит такой путь, будет 404; - пользователь не найден: 404. В SQLAlchemy
session.get(User, user_id)возвращаетNone, аscalar_one()бросаетNoResultFound. В DjangoUser.objects.getбросаетUser.DoesNotExist, для вьюх естьget_object_or_404; - нет прав: 401 без аутентификации, 403 при попытке читать чужой профиль. Если сам факт существования пользователя секрет, отвечают 404;
- удалён или заблокирован: мягкое удаление обычно отдают как 404, реже 410;
- база недоступна:
OperationalError, таймаут пула. Это 503 или 500, без трейсбека в теле; - данные из другого сервиса: у
requestsтаймаута по умолчанию нет, запрос может висеть бесконечно. Уhttpxон есть, 5 секунд.
Хороший архитектурный ответ: сервисный слой бросает доменное исключение UserNotFound и ничего не знает про HTTP, а перевод в статус делает один обработчик, в FastAPI через @app.exception_handler. Неожиданные ошибки пишутся через logger.exception с идентификатором запроса, клиенту уходит короткое сообщение и тот же идентификатор.
Где спотыкаются
Ловят except Exception и возвращают 500 на всё, включая «не найден». Клиент не может отличить свою ошибку от падения сервера.
Отдают 200 с {"error": ...} или null в теле. Мониторинг такое не видит, а фронтенду приходится разбирать каждый ответ.
Забывают про авторизацию. Эндпоинт, который отдаёт любого пользователя по id без проверки владельца, это классическая уязвимость IDOR, и интервьюер часто ведёт разговор именно к ней.