Le modèle de gestion des erreurs Swift 2 présente deux points importants: l'exhaustivité et la résilience. Ensemble, ils se résument à votre déclaration do
/ catch
devant attraper toutes les erreurs possibles, pas seulement celles que vous savez que vous pouvez lancer.
Notez que vous ne déclarez pas les types d'erreurs qu'une fonction peut générer, mais uniquement si elle génère du tout. C'est une sorte de problème zéro-un-infini: en tant que personne définissant une fonction pour les autres (y compris votre futur moi) à utiliser, vous ne voulez pas avoir à obliger chaque client de votre fonction à s'adapter à chaque changement dans l'implémentation de votre fonction, y compris les erreurs qu'il peut générer. Vous voulez que le code qui appelle votre fonction résiste à ce changement.
Parce que votre fonction ne peut pas dire quel type d'erreurs elle génère (ou pourrait générer à l'avenir), les catch
blocs qui interceptent les erreurs ne savent pas quels types d'erreurs elle pourrait générer. Ainsi, en plus de gérer les types d'erreur que vous connaissez, vous devez gérer ceux que vous ne connaissez pas avec une catch
instruction universelle - de cette façon, si votre fonction modifie l'ensemble des erreurs qu'elle génère à l'avenir, les appelants verront toujours son les erreurs.
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)
}
Mais ne nous arrêtons pas là. Pensez encore à cette idée de résilience. La façon dont vous avez conçu votre sandwich, vous devez décrire les erreurs à chaque endroit où vous les utilisez. Cela signifie que chaque fois que vous modifiez l'ensemble des cas d'erreur, vous devez changer chaque endroit qui les utilise ... pas très amusant.
L'idée derrière la définition de vos propres types d'erreur est de vous permettre de centraliser des choses comme ça. Vous pouvez définir une description
méthode pour vos erreurs:
extension SandwichError: CustomStringConvertible {
var description: String {
switch self {
case NotMe: return "Not me error"
case DoItYourself: return "Try sudo"
}
}
}
Et puis votre code de gestion des erreurs peut demander à votre type d'erreur de se décrire - désormais, chaque endroit où vous gérez des erreurs peut utiliser le même code et gérer d'éventuels futurs cas d'erreur.
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch let error as SandwichError {
print(error.description)
} catch {
print("i dunno")
}
Cela ouvre également la voie à des types d'erreur (ou à des extensions sur eux) pour prendre en charge d'autres moyens de signaler des erreurs - par exemple, vous pourriez avoir une extension sur votre type d'erreur qui sait comment présenter une UIAlertController
pour signaler l'erreur à un utilisateur iOS.