Recherche…


Remarques

Pour plus d'informations sur les erreurs, voir le langage de programmation Swift .

Bases de traitement des erreurs

Les fonctions dans Swift peuvent renvoyer des valeurs, lancer des erreurs ou les deux:

func reticulateSplines()                // no return value and no error
func reticulateSplines() -> Int         // always returns a value
func reticulateSplines() throws         // no return value, but may throw an error
func reticulateSplines() throws -> Int  // may either return a value or throw an error

Toute valeur conforme au protocole ErrorType (y compris les objets NSError) peut être considérée comme une erreur. Les énumérations constituent un moyen pratique de définir des erreurs personnalisées:

2,0 2,2
enum NetworkError: ErrorType {
    case Offline
    case ServerError(String)
}
3.0
enum NetworkError: Error {
    // Swift 3 dictates that enum cases should be `lowerCamelCase`
    case offline
    case serverError(String)
}

Une erreur indique une défaillance non fatale au cours de l'exécution du programme et est traitée avec les constructions de contrôle-flux spécialisées do / catch , throw et try .

func fetchResource(resource: NSURL) throws -> String {
    if let (statusCode, responseString) = /* ...from elsewhere...*/ {
        if case 500..<600 = statusCode {
            throw NetworkError.serverError(responseString)
        } else {
            return responseString
        }
    } else {
        throw NetworkError.offline
    }
}

Les erreurs peuvent être détectées avec do / catch :

do {
    let response = try fetchResource(resURL)
    // If fetchResource() didn't throw an error, execution continues here:
    print("Got response: \(response)")
    ...
} catch {
    // If an error is thrown, we can handle it here.
    print("Whoops, couldn't fetch resource: \(error)")
}

Toute fonction pouvant générer une erreur doit être appelée en utilisant try , try? ou try! :

// error: call can throw but is not marked with 'try'
let response = fetchResource(resURL)

// "try" works within do/catch, or within another throwing function:
do {
    let response = try fetchResource(resURL)
} catch {
    // Handle the error
}

func foo() throws {
    // If an error is thrown, continue passing it up to the caller.
    let response = try fetchResource(resURL)
}

// "try?" wraps the function's return value in an Optional (nil if an error was thrown).
if let response = try? fetchResource(resURL) {
    // no error was thrown
}

// "try!" crashes the program at runtime if an error occurs.
let response = try! fetchResource(resURL)

Attraper différents types d'erreur

Créons notre propre type d'erreur pour cet exemple.

2.2
enum CustomError: ErrorType {
    case SomeError
    case AnotherError
}

func throwing() throws {
    throw CustomError.SomeError
}
3.0
enum CustomError: Error {
    case someError
    case anotherError
}

func throwing() throws {
    throw CustomError.someError
}

La syntaxe Do-Catch permet de détecter une erreur générée et crée automatiquement une error nommée constante disponible dans le bloc catch :

do {
    try throwing()
} catch {
    print(error)
}

Vous pouvez également déclarer une variable vous-même:

do {
    try throwing()
} catch let oops {
    print(oops)
}

Il est également possible de chaîner différents énoncés de catch . Ceci est pratique si plusieurs types d'erreurs peuvent être générés dans le bloc Do.

Ici, le Do-Catch tentera d'abord de CustomError l'erreur en CustomError , puis en NSError si le type personnalisé n'a pas été NSError .

2.2
do {
    try somethingMayThrow()
} catch let custom as CustomError {
    print(custom)
} catch let error as NSError {
    print(error)
}
3.0

Dans Swift 3, pas besoin de baisser explicitement vers NSError.

do {
    try somethingMayThrow()
} catch let custom as CustomError {
    print(custom)
} catch {
    print(error)
}

Modèle de capture et de commutation pour la gestion explicite des erreurs

class Plane {
    
    enum Emergency: ErrorType {
        case NoFuel
        case EngineFailure(reason: String)
        case DamagedWing
    }

    var fuelInKilograms: Int

    //... init and other methods not shown

    func fly() throws {
        // ...
        if fuelInKilograms <= 0 {
            // uh oh...
            throw Emergency.NoFuel
        }
    }

}

Dans la classe client:

let airforceOne = Plane()
do {
    try airforceOne.fly()
} catch let emergency as Plane.Emergency {
    switch emergency {
    case .NoFuel:
        // call nearest airport for emergency landing
    case .EngineFailure(let reason):
        print(reason) // let the mechanic know the reason
    case .DamagedWing:
        // Assess the damage and determine if the president can make it
    }
}

Désactivation de la propagation des erreurs

Les créateurs de Swift ont mis beaucoup d’attention à ce que le langage soit expressif et que la gestion des erreurs soit tout à fait expressive. Si vous essayez d'appeler une fonction pouvant générer une erreur, l'appel de la fonction doit être précédé du mot-clé try. Le mot clé try n'est pas magique. Tout ce qu'il fait, c'est de sensibiliser le développeur à la capacité de lancement de la fonction.

Par exemple, le code suivant utilise une fonction loadImage (atPath :), qui charge la ressource image sur un chemin donné ou génère une erreur si l'image ne peut pas être chargée. Dans ce cas, étant donné que l'image est livrée avec l'application, aucune erreur ne sera générée lors de l'exécution. Par conséquent, il est recommandé de désactiver la propagation des erreurs.

let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")

Créer une erreur personnalisée avec une description localisée

Créer un enum d'erreurs personnalisées

enum RegistrationError: Error {
    case invalidEmail
    case invalidPassword
    case invalidPhoneNumber
}

Créer une extension de RegistrationError pour gérer la description localisée.

extension RegistrationError: LocalizedError {
    public var errorDescription: String? {
        switch self {
        case .invalidEmail:
            return NSLocalizedString("Description of invalid email address", comment: "Invalid Email")
        case .invalidPassword:
            return NSLocalizedString("Description of invalid password", comment: "Invalid Password")
        case .invalidPhoneNumber:
            return NSLocalizedString("Description of invalid phoneNumber", comment: "Invalid Phone Number")
        }
    }
}

Erreur de manipulation:

let error: Error = RegistrationError.invalidEmail
print(error.localizedDescription)


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow