Операторы обработки ошибок
Восстанавливайтесь с помощью catch, retry и replaceError.
«Операторы обработки ошибок» — бесплатный урок Swift Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Ошибки в Combine
У publisher в Combine есть тип ошибки. Когда publisher завершается с ошибкой, он прекращает поток — новые значения больше не отправляются. Чтобы создавать устойчивые конвейеры, нужны операторы, которые могут обрабатывать, преобразовывать ошибки или восстанавливаться после них.
Тип ошибки
Каждый publisher объявляет Output и Failure. Конвейер компилируется только тогда, когда типы ошибок согласованы, поэтому часто используются операторы, изменяющие ошибки.
let publisher: AnyPublisher<Data, URLError> = apiClient.request()
// Output = Data, Failure = URLErrorПерехват
Перехват перехватывает ошибку и заменяет завершившийся с ошибкой publisher новым. Это позволяет предоставить резервные значения, если что-то пошло не так.
apiClient.fetchUser()
.catch { error in
Just(User.guest)
}
.sink { user in
print("Got", user.name)
}
.store(in: &cancellables)replaceError
replaceError(with:) — это упрощённая форма catch: она заменяет любую ошибку одним резервным значением и успешно завершает поток.
apiClient.fetchCount()
.replaceError(with: 0)
.sink { count in
self.badge.text = "\(count)"
}
.store(in: &cancellables)retry
retry(n) повторно подписывается на publisher upstream до n раз, если тот завершился с ошибкой. Этот оператор идеально подходит для временных сетевых ошибок.
apiClient.fetchData()
.retry(3)
.sink(receiveCompletion: { print($0) },
receiveValue: { print($0) })
.store(in: &cancellables)Сочетание retry и перехвата
Распространённый отказоустойчивый шаблон: несколько раз выполнить retry, а затем использовать catch, чтобы перейти к резервному варианту, если все попытки завершились неудачей.
apiClient.fetchData()
.retry(2)
.catch { _ in
Just(Data())
}
.sink { data in
self.process(data)
}
.store(in: &cancellables)mapError
mapError преобразует один тип ошибки в другой. Это необходимо, чтобы объединять разные ошибки источников в единый тип ошибок уровня приложения.
enum AppError: Error { case network }
apiClient.request()
.mapError { _ in AppError.network }
.sink(receiveCompletion: { _ in }, receiveValue: { _ in })
.store(in: &cancellables)Почему важен mapError
При объединении издателей их типы Failure должны совпадать. mapError нормализует несовместимые ошибки, благодаря чему такие операторы, как merge и zip, компилируются, а ваш sink обрабатывает один тип ошибок.
setFailureType
У некоторых издателей, например у Just, тип ошибки — Never. setFailureType(to:) связывает их с издателями, которые могут завершиться ошибкой.
Just(42)
.setFailureType(to: AppError.self)
.merge(with: failablePublisher)
.sink(receiveCompletion: { _ in }, receiveValue: { _ in })
.store(in: &cancellables)Обработка завершения
В sink замыкание завершения сообщает, завершился ли поток успешно или с ошибкой. Проверяйте его, чтобы реагировать на ошибки, которые не были обработаны на предыдущих этапах.
publisher.sink(
receiveCompletion: { completion in
if case .failure(let error) = completion {
self.showAlert(error)
}
},
receiveValue: { value in
self.update(value)
}
).store(in: &cancellables)Проектирование отказоустойчивых конвейеров
Рекомендации по обработке ошибок:
- Используйте retry для временных сбоев
- Используйте перехват или replaceError для резервных вариантов
- Используйте mapError, чтобы унифицировать типы ошибок
- Всегда обрабатывайте случай сбоя в
sink
Быстрая проверка
Проверьте свои знания об обработке ошибок.
Повторение
Вы изучили операторы обработки ошибок во фреймворке Combine:
- перехват / replaceError — предоставляют резервные варианты
- retry — повторяет попытку после failure
- mapError / setFailureType — унифицируют типы ошибок
Вместе они позволяют создавать конвейеры, которые корректно продолжают работу при сбоях, а не прекращают её из-за первой ошибки.
Часто задаваемые вопросы
Урок «Операторы обработки ошибок» бесплатный?
Да — полный текст урока «Операторы обработки ошибок» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Операторы обработки ошибок»?
Восстанавливайтесь с помощью catch, retry и replaceError. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Операторы обработки ошибок»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Преобразование и объединение потоков
- Планировщики и потоки выполнения
- Операторы обработки ошибок
- Пользовательские издатели и подписчики