Non-Fatal Error — est une erreur qui ne met pas fin à l’application et permet de poursuivre l’exécution du programme. Contrairement à une erreur fatale, les erreurs non fatales peuvent être interceptées, traitées et journalisées sans perte de session utilisateur. Selon la Documentation Firebase Crashlytics, 2024, environ 70 % de toutes les erreurs enregistrées dans les applications de production sont non fatales, mais les ignorer conduit à l’accumulation de dette technique et à la dégradation progressive de l’expérience utilisateur. Le traitement correct des erreurs non fatales est l’une des compétences clés du développeur mobile.
Points clés
Non-Fatal Error — est une exception ou un état d’erreur qui n’entraîne pas l’arrêt du processus. L’application continue de fonctionner, mais peut être dans un état incorrect : les données ne se sont pas chargées, une requête n’a pas été envoyée, un élément d’interface ne s’est pas affiché. L’utilisateur soit ne remarque pas l’erreur, soit voit un message et continue d’utiliser l’application.
Une erreur non fatale laisse toujours un chemin de récupération au programme. Le gestionnaire d’erreurs peut fournir des données alternatives, répéter l’opération ou afficher un espace réservé dans l’interface. L’objectif principal est d’éviter un plantage et de maintenir une expérience utilisateur acceptable. Le développeur doit prévoir explicitement un scénario de récupération dans chaque bloc catch.
Selon Instabug 2024, 65 % des utilisateurs désinstallent une application après deux interactions échouées. Les erreurs non fatales laissées sans attention s’accumulent et dégradent la qualité globale. La journalisation et la correction systématiques des erreurs non fatales est un moyen direct d’améliorer la rétention et les évaluations dans les magasins d’applications.
Erreurs réseau sont le type le plus courant d’erreurs non fatales dans les applications mobiles. Délai d’expiration de connexion, perte de réseau, code d’état serveur incorrect — toutes ces situations sont interceptées et traitées sans plantage. Un message d’indisponibilité du service avec option de réessai est affiché à l’utilisateur. Le motif de réessai avec backoff exponentiel est typique pour les erreurs réseau.
Format de réponse serveur incorrect, champ obligatoire manquant, type de données invalide — les erreurs d’analyse sont non fatales si l’application traite correctement les données mal formées. L’approche typique consiste à utiliser des valeurs de repli par défaut et à journaliser l’erreur d’analyse avec le contexte de la requête pour une analyse ultérieure côté serveur.
Problèmes de chargement d’images, polices incorrectes, erreurs de mise en page — toutes sont non fatales mais dégradent l’expérience utilisateur. Les images d’espace réservé et les valeurs de repli aident à éviter les écrans vides et rendent les erreurs moins visibles. Dans React Native, on utilise Error Boundary pour les erreurs d’interface avec affichage d’un composant de repli.
Erreurs de calcul, incohérences d’état, transitions incorrectes entre écrans — les erreurs logiques n’entraînent souvent pas de plantage mais conduisent à un comportement incorrect de l’application. Elles sont plus difficiles à détecter sans journalisation et surveillance systématiques car elles ne génèrent pas de rapport de plantage et restent inaperçues jusqu’à une réclamation d’utilisateur.
Non-Fatal Error se distingue de l’erreur fatale en ce qu’elle laisse au programme une chance de continuer à fonctionner. Une erreur fatale est un état dont l’application ne peut pas se remettre : déréférencement de pointeur nul, débordement de pile, manque de mémoire. Une erreur non fatale peut être interceptée, traitée et l’exécution peut continuer, tandis qu’une erreur fatale nécessite un redémarrage de l’application.
| Caractéristique | Non-Fatal Error | Fatal Error |
|---|---|---|
| Arrêt de l’app | Non | Oui |
| Récupération possible | Oui, via catch | Non |
| Journalisation | Depuis le code via recordException | Uniquement par le rapporteur de plantage |
| Impact UX | Désagrément temporaire | Échec complet de la session |
| Exemple | Délai d’expiration réseau, erreur d’analyse | NullPointerException, OOM |
La frontière entre non fatal et fatal peut dépendre de l’implémentation. Un délai d’expiration réseau dans une application est traité comme non fatal (réessai après 1–2 secondes), tandis que dans une autre il peut être fatal (plantage si aucun gestionnaire n’existe). Un traitement des erreurs de qualité transforme les situations potentiellement fatales en non fatales, augmentant la stabilité de l’application. Conçevoir un système de gestion des erreurs est l’une des tâches architecturales clés lors du développement d’une application mobile avec des exigences élevées de fiabilité. Un système de surveillance intégré permet à l’équipe de détecter et corriger rapidement les erreurs non fatales avant qu’elles n’affectent un nombre significatif d’utilisateurs.
Firebase Crashlytics est l’outil principal pour journaliser les erreurs non fatales dans les applications mobiles. La méthode recordException permet de capturer une exception non fatale avec une trace de pile complète et un contexte d’exécution sans interrompre l’application. Contrairement aux rapports de plantage, recordException peut être appelé n’importe où dans le code pour journaliser les exceptions interceptées.
fun fetchUserData(userId: String) {
try {
val response = apiService.getUser(userId)
updateUI(response)
} catch (e: IOException) {
Crashlytics.log("Network error for user $userId")
Crashlytics.recordException(e)
showRetryDialog()
} catch (e: JsonParseException) {
// Non-fatal : utilisation des données de repli
Crashlytics.recordException(e)
showFallbackContent()
}
}
// Journalisation avec clés personnalisées
Crashlytics.setCustomKey("screen", "Profile")
Crashlytics.setCustomKey("api_version", "v3")
Sentry est une alternative à Crashlytics avec un diagnostic plus détaillé pour les erreurs non fatales. Le SDK Sentry fournit la méthode captureException, qui envoie les détails de l’exception au serveur. L’avantage clé de Sentry est le regroupement des erreurs non fatales similaires en un seul issue, l’analyse de la fréquence de récurrence et la fourniture du contexte d’exécution sous forme de breadcrumbs — la séquence des actions de l’utilisateur avant l’erreur.
Toutes les erreurs non fatales ne nécessitent pas d’être journalisées. Les états attendus — échec réseau en l’absence de connexion — peuvent être journalisés sélectivement. Les erreurs inattendues — NullPointerException dans du code traité, format de données invalide, erreurs logiques — doivent toujours être journalisées. Chaque équipe définit son seuil d’importance : en moyenne, 10 à 20 erreurs non fatales uniques pour 1000 utilisateurs par jour est considéré comme normal. Il est important de configurer des alertes pour une augmentation brutale des erreurs non fatales — cela peut indiquer des problèmes avec une nouvelle version d’API ou une régression après une publication.
Le mécanisme de base est try-catch, qui intercepte l’exception et exécute le code de récupération. Pour les opérations réseau, le motif typique est le réessai avec backoff exponentiel. Pour les erreurs d’analyse, l’approche consiste à utiliser des valeurs de repli par défaut et à journaliser le contexte pour une analyse ultérieure côté serveur.
func loadImage(from url: URL) -> UIImage? {
do {
let data = try Data(contentsOf: url)
return UIImage(data: data)
} catch {
Logger.shared.logError(error: "Image load failed: \(url)")
return UIImage(named: "placeholder")
}
}
func performRequest() async throws -> Data {
var lastError: Error? = nil
for attempt in 0..<3 {
do {
return try await URLSession.shared.data(from: url)
} catch {
lastError = error
try await Task.sleep(UInt64(pow(2, attempt)) * 1_000_000_000)
}
}
throw lastError ?? URLError(.unknown)
}
Types Result — une approche alternative sans exceptions. Une fonction retourne une classe scellée Result avec les variantes Success et Failure. Le code appelant traite les deux variantes explicitement, éliminant les erreurs non traitées. Les types Result sont populaires en Kotlin (Result
Pour chaque type d’erreur non fatale, une stratégie de récupération doit être planifiée : charger les données en cache en cas d’erreur réseau, utiliser des valeurs par défaut en cas d’erreur d’analyse, réinitialiser un composant en cas d’erreur d’interface. Une bonne pratique consiste à afficher à l’utilisateur un toast ou snackbar avec un message d’erreur sans bloquer complètement l’interaction avec l’application. Il est important de distinguer les erreurs récupérables des erreurs non récupérables — pour ces dernières, la stratégie de récupération sera différente, comme suggérer de redémarrer l’écran ou d’effacer les données. La mise en cache de l’état réussi précédent est souvent la manière la plus simple et la plus efficace de gérer les erreurs non fatales sur les plateformes mobiles.
Questions fréquentes
Avertissement est un avertissement du compilateur ou de l’analyseur statique concernant un problème potentiel dans le code. Une erreur non fatale est une exception d’exécution qui s’est déjà produite mais n’a pas causé de plantage. Un avertissement peut être corrigé avant la compilation ; une erreur non fatale doit être traitée pendant l’exécution via un bloc catch.
Non, une journalisation excessive encombre la surveillance. Les erreurs inattendues en production doivent être journalisées, tandis que les états attendus doivent être ignorés : l’échec réseau hors connexion peut être journalisé sélectivement, mais un NullPointerException dans du code traité doit toujours être journalisé. Chaque équipe définit son seuil d’importance en fonction du contexte de l’application.
Dans SwiftUI, on utilise ObservableObject avec un champ @Published errorState pour suivre l’état d’erreur. La vue s’abonne aux changements et affiche un contenu alternatif. Avant iOS 17, on utilisait Combine avec des gestionnaires ; à partir d’iOS 17, on utilise SwiftData et les macros @Observable pour les mises à jour réactives de l’interface.
Oui, si l’erreur déclenche une réaction en chaîne. Exemple : un échec non fatal de chargement d’image peut conduire à un état d’interface incorrect, qui provoque ensuite un plantage lors de la tentative d’affichage. Un traitement de qualité des erreurs non fatales à chaque niveau empêche leur escalade vers un niveau fatal.
Sous iOS, les erreurs non fatales sont traitées via do-catch avec throw ; sous Android, via try-catch avec des exceptions. iOS utilise NSError avec des domaines et des codes d’erreur ; Android utilise des exceptions Java/Kotlin. Crashlytics fonctionne de manière identique sur les deux plateformes via recordException, fournissant une interface de surveillance unifiée.
Résumé
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.
Lisez aussi