0Pricing
Swift Academy · Урок

Операторы обработки ошибок

Восстанавливайтесь с помощью 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 — локальная установка не требуется.

Все уроки этого курса

  1. Преобразование и объединение потоков
  2. Планировщики и потоки выполнения
  3. Операторы обработки ошибок
  4. Пользовательские издатели и подписчики
← Назад к Swift Academy