Где должна происходить обработка ошибок: в сервисе или в UI
Что проверяют
Умеете ли вы разделить ответственность: кто ловит ошибку, кто переводит её в понятный вид, а кто показывает. Правильный ответ «в обоих местах, но с разными задачами». Следом обычно спрашивают, как ошибка сети превращается в текст на экране и что делать с отменой запроса.
Как отвечать
Опишите путь ошибки по слоям:
- сервисный слой: ловит низкоуровневые ошибки (
URLError, коды HTTP,DecodingError), чинит то, что можно починить на месте (повтор с задержкой при таймауте, обновление токена при 401), а остальное переводит в доменную ошибку вродеenum OrderError: Error { case notFound, paymentDeclined, offline }. Здесь же логирование черезLoggerи отправка нефатальных ошибок в крэш-репортер. Алерты сервис не показывает и про UIKit не знает; - ViewModel или Presenter: превращает доменную ошибку в состояние экрана, например
.failed(message:retryable:), решает, показать ли кнопку «Повторить» или откатить оптимистичное обновление; - View: только отображает состояние: баннер, алерт, пустой экран с ошибкой.
Инструменты Swift: throws и async throws, Result<Success, Failure> для колбэков, а с Swift 6 типизированный throws(OrderError), если набор ошибок закрыт. Для текста пользователю есть протокол LocalizedError с errorDescription, но формулировки лучше собирать в слое представления, а не в сервисе.
Отдельно скажите про отмену: CancellationError и URLError с кодом .cancelled при уходе с экрана не ошибка для пользователя, их тихо пропускают.
Где спотыкаются
Показывают UIAlertController прямо из сервиса или синглтона. Такой сервис не переиспользовать и не протестировать, а при двух параллельных ошибках алерты налезают друг на друга.
Глушат ошибки через try? или пустой catch. Экран остаётся с вечным индикатором загрузки, а в логах пусто.
Выводят пользователю системный error.localizedDescription. Он получается техническим, часто на английском и без подсказки, что делать дальше.