Ответ
Error — это тип, представляющий ошибки времени выполнения в Swift. Все ошибки соответствуют протоколу Error.
Базовый пример с enum:
enum NetworkError: Error {
case invalidURL
case timeout(seconds: Int)
case serverError(statusCode: Int)
}
// Функция, которая может выбросить ошибку
func fetchData(from urlString: String) throws -> Data {
guard let url = URL(string: urlString) else {
throw NetworkError.invalidURL
}
// ... реализация запроса
}
Обработка ошибок:
do {
let data = try fetchData(from: "https://api.example.com")
process(data)
} catch NetworkError.timeout(let seconds) {
print("Таймаут через (seconds) секунд")
} catch NetworkError.serverError(let code) where code == 500 {
print("Внутренняя ошибка сервера")
} catch {
print("Неизвестная ошибка: (error.localizedDescription)")
}
Сокращённые формы:
// try? — возвращает nil при ошибке
if let data = try? fetchData(from: urlString) { /* обработка */ }
// try! — принудительное извлечение (крашнет при ошибке)
let data = try! fetchData(from: guaranteedValidURL)
// defer — гарантированное выполнение кода
func readFile() throws -> String {
let file = openFile()
defer { closeFile(file) } // Выполнится в любом случае
return try parseFile(file)
} Ответ 18+ 🔞
О, слушай, ну вот, блядь, пришло время поговорить про Error в Swift. Это, сука, такой тип, который олицетворяет все наши косяки и просчёты во время работы программы. Всякая хуйня, которая может пойти не так, должна соответствовать протоколу Error. Без этого нихуя не выбросишь.
Вот, смотри, как это обычно выглядит, на примере enum:
enum NetworkError: Error {
case invalidURL
case timeout(seconds: Int)
case serverError(statusCode: Int)
}
// Функция, которая может тебе впендюрить ошибку
func fetchData(from urlString: String) throws -> Data {
guard let url = URL(string: urlString) else {
throw NetworkError.invalidURL
}
// ... тут типа запрос куда-то делается
}
А теперь, блядь, самое интересное — как эту ошибку ловить, чтобы всё не накрылось медным тазом:
do {
let data = try fetchData(from: "https://api.example.com")
process(data)
} catch NetworkError.timeout(let seconds) {
print("Таймаут, блядь, через (seconds) секунд — сервер уснул")
} catch NetworkError.serverError(let code) where code == 500 {
print("Ёпта, внутренняя ошибка сервера, всё пропало!")
} catch {
print("Хуй знает что случилось, но случилось: (error.localizedDescription)")
}
Есть ещё, блядь, короткие пути, для ленивых или самоуверенных:
// try? — если похуй на ошибку, вернёт nil
if let data = try? fetchData(from: urlString) { /* ну ок, работаем */ }
// try! — это когда ты, блядь, на 146% уверен, что всё будет ок. Если нет — краш и пиздец.
let data = try! fetchData(from: guaranteedValidURL)
// defer — это, сука, магия. Код выполнится в любом случае, даже если всё пошло по пизде.
func readFile() throws -> String {
let file = openFile()
defer { closeFile(file) } // Вызовется в конце, хоть ты тресни!
return try parseFile(file)
}
Вот и вся магия, ёпта. Либо ловишь ошибки, либо они ловят тебя.