Do-Catch : ce que c’est, construction et gestion d’erreurs en Swift

Auteur : IT Sectr Publié le : 2026-05-26 Temps de lecture : 8 min

Do-Catch est une construction du langage Swift pour la gestion d’erreurs qui intercepte les exceptions levées via throw et exécute le bloc de code correspondant. Contrairement au try-catch traditionnel dans d’autres langages, Swift exige un marquage explicite des fonctions qui peuvent lever une erreur avec le modificateur throws. Selon Swift.org, 2026, Do-Catch est le mécanisme principal de gestion d’erreurs en Swift, offrant la sécurité de types.

Points clés

  • Do-Catch est une construction Swift qui intercepte les erreurs des blocs avec try et throw.
  • throws est un marqueur de fonction indiquant qu’elle peut lever une erreur.
  • try est le mot-clé pour appeler une fonction throwing dans un bloc do.
  • catch est le bloc de gestion d’erreurs avec correspondance de motifs par type.
  • try? et try! sont des formes alternatives qui convertissent les erreurs en nil ou provoquent un crash.

Qu’est-ce que Do-Catch ?

Do-Catch est une construction en Swift consistant en un bloc do, à l’intérieur duquel du code capable de lever une erreur est exécuté, et un ou plusieurs blocs catch qui traitent cette erreur. Le bloc do contient des appels à des fonctions throwing marquées avec try, et les blocs catch correspondent à l’erreur par type.

Swift implémente un modèle de gestion structurée des erreurs, différent des exceptions en Objective-C. Ici, une erreur n’est pas une exception avec déroulement de pile, mais une valeur conforme au protocole Error. Lever une erreur via throw transfère le contrôle au bloc catch le plus proche sans la surcharge du déroulement de pile.

Une caractéristique clé de Swift est la gestion explicite. Le compilateur ne permet pas d’appeler une fonction throwing sans try, do-catch ou un mécanisme alternatif (try?, try!). Cela élimine les situations où une erreur passe inaperçue.

Modèle d’erreurs en Swift : protocole Error et fonctions throwing

Au cœur de la gestion d’erreurs en Swift se trouve le protocole Error. Tout type conforme à ce protocole peut être levé via throw. Les erreurs sont généralement définies comme une enum conforme à Error.

Protocole Error

Error est un protocole vide (marqueur). Il ne nécessite pas d’implémentation de méthodes, seulement la conformité. Le compilateur Swift utilise Error pour la vérification statique : une fonction avec throws ne peut lever qu’une valeur conforme à Error.

Fonctions Throwing

Une fonction marquée avec throws doit être appelée avec try. Si un throw se produit à l’intérieur de cette fonction, le contrôle est transféré au do-catch appelant. Si l’erreur n’est traitée nulle part dans la chaîne d’appels, elle se propage au niveau supérieur.

swift
enum FileError: Error {
    case notFound
    case permissionDenied
    case corrupted(String)
}

func readFile(path: String) throws -> String {
    guard FileManager.default.fileExists(atPath: path) else {
        throw FileError.notFound
    }
    return try String(contentsOfFile: path)
}

Rethrows

rethrows est un modificateur pour les fonctions qui acceptent une closure throwing comme paramètre. Si la closure passée ne lève pas d’erreur, la fonction rethrows peut être appelée sans try. Cela permet d’écrire des fonctions génériques d’ordre supérieur compatibles avec les closures throwing et non-throwing.

Syntaxe de Do-Catch : plusieurs blocs catch

Swift prend en charge plusieurs blocs catch avec correspondance d’erreurs par type. Cela ressemble à when en Kotlin ou un switch par type : le premier catch correspondant est exécuté, les autres sont ignorés.

Correspondance par type

Chaque bloc catch peut contenir un motif correspondant à un type d’erreur spécifique. Swift vérifie les blocs dans l’ordre, donc les types plus spécifiques doivent venir avant les types généraux. Si aucun motif ne correspond, le bloc catch sans motif est exécuté.

Traitement de plusieurs types

La sécurité de types de Do-Catch permet de traiter chaque erreur séparément ou de combiner plusieurs types dans un bloc via une correspondance de motifs séparée par des virgules. Cela élimine les chaînes if-else lourdes typiques d’Objective-C, où l’analyse d’erreurs se faisait via des codes de retour ou NSError avec vérification de domaine et de code.

Swift prend également en charge catch where — correspondance avec une condition supplémentaire. Par exemple, vous pouvez filtrer les erreurs par un code ou un texte spécifique : catch URLError where error.code == .notConnectedToInternet. Cela réduit le nombre de blocs catch tout en maintenant la précision.

Pour déboguer les fonctions throwing, Swift fournit une distinction entre erreurs et exceptions. Une erreur Swift est une valeur de retour qui ne nécessite pas de déroulement de pile. Les exceptions Objective-C (@try/@catch) fonctionnent au niveau de l’exécution et ne sont utilisées que pour les échecs fatals. Do-Catch traite les erreurs, pas les exceptions, ce qui le rend prévisible et performant.

Lors du développement de bibliothèques et SDK, il est important de se rappeler que les fonctions throwing font partie du contrat public. Le type d’erreur n’est pas spécifié dans la signature, donc documentez les erreurs qu’une fonction peut lever dans les commentaires ou via des enum de type Result. Cela aide les utilisateurs d’API à écrire des blocs catch corrects sans avoir à consulter l’implémentation.

Dans le contexte de la programmation asynchrone, Do-Catch avec async/await résout le problème de l’enfer des callbacks. Auparavant en Swift, la gestion d’erreurs dans le code asynchrone nécessitait des closures imbriquées avec vérification de Error? dans les gestionnaires d’achèvement. Avec async/await et Do-Catch, le code asynchrone throwing ressemble à du code synchrone, simplifiant la lecture et la maintenance de chaînes de requêtes complexes avec gestion d’erreurs à chaque étape.

swift
do {
    let content = try readFile(path: "/data/config.json")
    process(content)
} catch FileError.notFound {
    createDefaultConfig()
} catch FileError.permissionDenied {
    requestAccess()
} catch FileError.corrupted(let detail) {
    logCorruption(detail)
} catch {
    print("Erreur inconnue : \(error)")
}

Variations de try : try, try?, try! et quand les utiliser

Swift offre trois façons d’appeler les fonctions throwing : try, try? et try!. Chaque option résout une tâche spécifique et a ses limites.

try — Appel standard

try est utilisé dans un bloc do, et l’erreur est traitée dans catch. C’est la façon principale d’appeler les fonctions throwing. Le compilateur exige que try soit dans un contexte où l’erreur peut être interceptée.

try? — Conversion en Optional

try? convertit le résultat d’une fonction throwing en Optional. Si la fonction lève une erreur, try? retourne nil, sinon retourne un Optional avec la valeur réussie. Utile pour les appels où l’erreur peut être ignorée mais un indicateur de succès est nécessaire.

try! — Exécution forcée

try! supprime la gestion d’erreurs. Si la fonction throwing lève une erreur, l’application se termine avec une erreur d’exécution. Utilisez try! seulement lorsque vous êtes absolument sûr que l’erreur est impossible — par exemple, lors du chargement d’une ressource intégrée.

swift
// try? — nous ignorons l’erreur, obtenons nil en cas d’échec
if let data = try? Data(contentsOf: url) {
    processData(data)
}

// try! — seulement si l’erreur est garantie impossible
let bundled = try! String(contentsOfFile: "Assets/default.txt")

// try — option standard dans do-catch
do {
    let result = try performNetworkRequest()
    updateUI(result)
} catch {
    showError(error)
}

Do-Catch dans le développement iOS : exemples pratiques

Do-Catch est activement utilisé dans le développement iOS pour travailler avec les API système. Considérons des scénarios typiques : travail avec le système de fichiers, Core Data et les requêtes réseau.

Système de fichiers

De nombreuses méthodes de FileManager sont throwing. Do-Catch permet de traiter correctement l’absence de fichier, l’occupation de ressource ou les permissions insuffisantes.

Requêtes réseau avec Codable

L’analyse JSON via JSONDecoder est une opération throwing. Do-Catch intercepte les erreurs de décodage et les échecs réseau séparément, fournissant à l’utilisateur un message d’erreur précis.

swift
struct User: Codable {
    let id: Int
    let name: String
}

func fetchUser(id: Int) async throws -> User {
    let url = URL(string: "https://api.example.com/users/\(id)")!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// Appel avec traitement
do {
    let user = try await fetchUser(id: 42)
    showUser(user)
} catch let error as URLError {
    showNetworkAlert(error)
} catch let error as DecodingError {
    showParseError(error)
} catch {
    showGenericError(error)
}

Erreurs courantes avec Do-Catch

Les développeurs, en particulier ceux venant d’autres langages, commettent souvent des erreurs caractéristiques lors de l’utilisation de Do-Catch. Examinons les plus courantes.

  • Try oublié — appeler une fonction throwing sans try provoque une erreur de compilation. Swift ne permet pas d’ignorer implicitement les erreurs.
  • Catch vide — un bloc catch sans traitement cache l’erreur. Enregistrez ou traitez toujours l’erreur, même si elle semble impossible.
  • Catch sans correspondance — un seul catch générique pour toutes les erreurs perd les avantages de la sécurité de types. Séparez le traitement par types en utilisant plusieurs blocs.
  • Utilisation excessive de try! — try! dans le code de production est une source de crashes inattendus. Utilisez-le uniquement pour les ressources intégrées ou les tests.

Foire aux questions

En quoi Do-Catch en Swift diffère-t-il du try-catch dans d’autres langages ?

En Swift, une erreur est une valeur conforme au protocole Error, pas une exception avec déroulement de pile. Les fonctions throwing doivent être explicitement marquées avec throws, et le compilateur exige try lors de l’appel — cela élimine les erreurs non traitées à la compilation.

Peut-on utiliser Do-Catch avec async/await ?

Oui, les fonctions async peuvent aussi être throws, et do-catch fonctionne avec elles. Appeler une fonction async throwing nécessite try await dans un bloc do. C’est la façon standard de gérer les erreurs dans le code asynchrone Swift.

Comment gérer une erreur sans do-catch ?

Il existe des alternatives : try? convertit l’erreur en nil, try! provoque un crash en cas d’erreur, et rethrows permet de propager une erreur depuis une closure. Do-catch reste la façon principale de gestion explicite.

Une fonction peut-elle lever différents types d’erreurs ?

Swift ne type pas les erreurs levées — toute fonction throwing peut lever tout type conforme à Error. Séparez le traitement par correspondance dans catch par types d’erreurs spécifiques.

Dois-je encapsuler toutes les erreurs dans un type personnalisé ?

Oui, c’est une bonne pratique. Définissez AppError comme une enum conforme à Error et convertissez les erreurs système en erreurs de domaine. Cela unifie le traitement et isole la couche applicative des détails système.

Résumé

  • Do-Catch est une construction Swift pour la gestion d’erreurs avec marquage obligatoire throws sur les fonctions et try sur les appels.
  • Les erreurs Swift sont des valeurs conformes au protocole Error, pas des exceptions avec déroulement de pile, offrant une surcharge nulle en l’absence d’échec.
  • Les multiples catch permettent de traiter différents types d’erreurs séparément avec une correspondance de motifs similaire à switch.
  • try? convertit une erreur en nil pour les scénarios simples, try! est un appel forcé avec risque de crash, utilisé uniquement pour les opérations garanties.
  • Do-Catch avec async/await est la façon standard de gérer les erreurs dans le code asynchrone Swift en utilisant try await.
  • Évitez les blocs catch vides et l’utilisation excessive de try! — cela cache les erreurs et conduit à des crashes inattendus en production.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi