Что это такое?
Это лямбда‑функции (callback-обработчики), которые:
onSuccess— вызывается при успешном завершении операции;onError— вызывается при возникновении ошибки.
Они позволяют отделить логику обработки результата от самого выполнения операции.
Где применяются
Чаще всего встречаются в:
- сетевых запросах (Retrofit, Ktor);
- работе с БД (Room, SQLDelight);
- корутинах (async, await);
- RxJava/RxKotlin;
- библиотеках для работы с файлами/IO.
Базовый синтаксис
ВыделитьKotlin
someAsyncOperation(
onSuccess = { result ->
// Обработка успешного результата
},
onError = { exception ->
// Обработка ошибки
}
)Практические примеры
Сетевой запрос (Retrofit)
ВыделитьKotlin
apiService.getUser(userId)
.enqueue(object : Callback<User> {
override fun onResponse(call: Call<User>, response: Response<User>) {
if (response.isSuccessful) {
onSuccess(response.body()!!)
} else {
onError(HttpException(response))
}
}
override fun onFailure(call: Call<User>, t: Throwable) {
onError(t)
}
})Корутины с async
ВыделитьKotlin
scope.launch {
val deferred = async {
fetchDataFromNetwork()
}
try {
val result = deferred.await()
onSuccess(result)
} catch (e: Exception) {
onError(e)
}
}Пользовательский класс с callback-ами
ВыделитьKotlin
class DataLoader {
fun loadData(
onSuccess: (List<String>) -> Unit,
onError: (Throwable) -> Unit
) {
scope.launch {
try {
val data = fetchFromServer()
onSuccess(data)
} catch (e: IOException) {
onError(e)
}
}
}
}
// Использование:
dataLoader.loadData(
onSuccess = { data ->
println("Данные загружены: $data")
},
onError = { error ->
println("Ошибка: ${error.message}")
}
)Лучшие практики
Всегда обрабатывайте ошибки
Даже если просто логируете:
ВыделитьKotlin
onError = { e ->
Log.e("Network", "Ошибка загрузки", e)
}Используйте типобезопасные ошибки
ВыделитьKotlin
sealed class NetworkError {
data class HttpError(val code: Int) : NetworkError()
object Timeout : NetworkError()
}
onError = { error ->
when (error) {
is NetworkError.HttpError -> showHttpError(error.code)
is NetworkError.Timeout -> showTimeoutMessage()
}
}Не оставляйте onError пустым
Пустой
onError = {} скрывает проблемы.Используйте onSuccess для побочных эффектов
ВыделитьKotlin
onSuccess = { user ->
saveToCache(user)
updateUI(user)
trackAnalytics("user_loaded")
}Альтернативы
В современном Kotlin часто используют:
Result класс (встроенный в Kotlin 1.5+):
ВыделитьKotlin
fun fetchData(): Result<Data> { ... }
result.fold(
onSuccess = { /* ... */ },
onFailure = { /* ... */ }
)Sealed классы для типизированных результатов;
Flow/StateFlow для реактивного программирования.
Когда выбирать onSuccess/onError?
Используйте, если:
- работаете с legacy-кодом;
- используете библиотеки с callback-интерфейсами;
- нужна простая обработка без сложных цепочек.
Откажитесь, если:
- проект использует
FlowилиStateFlow; - нужна сложная композиция операций;
- требуется обработка нескольких событий.
Вывод
onSuccess и onError — это:
- простой способ обработки асинхронных результатов;
- стандартный паттерн в Kotlin;
- удобный инструмент для разделения логики успеха и ошибок.
Главное — всегда обрабатывать ошибки и не игнорировать возможные сбои.