У моделі поводження з помилками Swift 2 є два важливих моменти: вичерпність та стійкість. Разом вони зводяться до вашої do
/ catch
заяви, потребуючи виявити всі можливі помилки, а не лише ті, які ви знаєте, що можете викинути.
Зверніть увагу, що ви не декларуєте, які типи помилок може накидати функція, лише чи вона взагалі видає. Це проблема нуля однієї нескінченності: коли хтось визначає функцію для інших (включаючи майбутнє «я»), ви не хочете, щоб кожен клієнт вашої функції пристосовувався до кожної зміни в реалізації вашої функція, включаючи, які помилки вона може викликати. Ви хочете, щоб код, який викликає вашу функцію, був стійким до таких змін.
Оскільки ваша функція не може сказати, які помилки вона викидає (чи може бути викинута в майбутньому), catch
блоки, які вловлюють її помилки, не знають, які типи помилок вони можуть видавати. Отже, крім обробки типів помилок, про які ви знаєте, вам потрібно попрацювати з тими, яких ви не маєте, з універсальним catch
твердженням - таким чином, якщо ваша функція змінить набір помилок, які вона викидає в майбутньому, абоненти все одно будуть вловлювати її помилки.
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch SandwichError.NotMe {
print("Not me error")
} catch SandwichError.DoItYourself {
print("do it error")
} catch let error {
print(error.localizedDescription)
}
Але не будемо зупинятися на цьому. Подумайте ще про цю ідею стійкості. Те, як ви створили свій сендвіч, ви повинні описувати помилки в кожному місці, де ви їх використовуєте. Це означає, що щоразу, коли ви змінюєте набір випадків помилок, вам доведеться змінювати кожне місце, яке їх використовує ... не дуже весело.
Ідея визначення власних типів помилок полягає в тому, щоб ви могли централізувати подібні речі. Ви можете визначити description
метод для своїх помилок:
extension SandwichError: CustomStringConvertible {
var description: String {
switch self {
case NotMe: return "Not me error"
case DoItYourself: return "Try sudo"
}
}
}
І тоді ваш код обробки помилок може попросити ваш тип помилок описати себе - тепер кожне місце, де ви обробляєте помилки, може використовувати той самий код і також обробляти можливі майбутні випадки помилок.
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch let error as SandwichError {
print(error.description)
} catch {
print("i dunno")
}
Це також відкриває шлях для типів помилок (або розширень на них) для підтримки інших способів повідомлення про помилки - наприклад, ви можете мати розширення щодо свого типу помилки, яке знає, як подати UIAlertController
повідомлення про помилку користувачеві iOS.