В чем разница бизнес-логики и отображения ошибок в приложении?
Что проверяют
Понимаете ли вы, где в Android-приложении проходит граница между решением «что произошло» и решением «как это показать». Следом обычно просят провести ошибку от репозитория до экрана и спрашивают, как передать одноразовое событие вроде Snackbar.
Как отвечать
Бизнес-логика решает, допустима ли операция и чем она закончилась. Отображение решает, какой текст и какой элемент увидит пользователь. Разнесите это по слоям:
- data-слой: ловит
IOException,HttpException, ошибки базы и переводит их в доменные типы, чтобы наружу не утекали детали Retrofit или Room; - domain-слой (UseCase): возвращает результат в виде
sealed interface, напримерTransferError.InsufficientFundsилиTransferError.LimitExceeded. Здесь нетContext, строковых ресурсов и Android-зависимостей, поэтому код тестируется обычным JUnit; - ViewModel: переводит доменную ошибку в состояние экрана,
UiStateс полем ошибки или@StringRes-идентификатором, и отдаёт его черезStateFlow; - UI (Compose или View): выбирает форму показа. Ошибка ввода подсвечивается под полем, сетевой сбой показывается Snackbar с кнопкой «Повторить», критическая ошибка получает отдельный экран.
Пример из банковского сценария: правило «сумма перевода не больше баланса» живёт в UseCase, а фраза «Недостаточно средств, пополните счёт» и выбор между диалогом и подсказкой под полем живут в UI.
Про события: рекомендация Google сейчас такая: хранить ошибку в состоянии, а после показа сообщать ViewModel, что она обработана. Channel тоже встречается, но тогда объясните, как вы не теряете событие при повороте экрана.
Где спотыкаются
Показывают пользователю e.message или e.localizedMessage. Это текст для разработчика, на экране он выглядит как «Unable to resolve host» и пугает.
Тянут Context или getString() в UseCase и репозиторий ради текста ошибки. Логика перестаёт тестироваться без Android, а тексты не переключаются при смене языка.
Оборачивают корутину в runCatching или ловят общий Exception. Так проглатывается CancellationException, отмена перестаёт работать, и пользователь видит ложную ошибку уже после ухода с экрана.