Non-Fatal Error — ist ein Fehler, der die Anwendung nicht beendet und die Fortsetzung der Programmausführung ermöglicht. Im Gegensatz zu einem fatalen Fehler können nicht-fatale Fehler abgefangen, behandelt und protokolliert werden, ohne dass die Benutzersitzung verloren geht. Laut der Firebase Crashlytics Dokumentation, 2024 sind etwa 70 % aller protokollierten Fehler in Produktionsanwendungen nicht-fatal, aber ihre Ignorierung führt zur Ansammlung technischer Schulden und zur allmählichen Verschlechterung der Benutzererfahrung. Die korrekte Behandlung von Non-Fatal-Fehlern ist eine der Schlüsselfähigkeiten eines mobilen Entwicklers.
Wichtige Punkte
Non-Fatal Error — ist eine Ausnahme oder ein Fehlerzustand, der keine Prozessbeendigung verursacht. Die Anwendung läuft weiter, kann sich aber in einem fehlerhaften Zustand befinden: Daten wurden nicht geladen, eine Anfrage wurde nicht gesendet, ein Oberflächenelement wurde nicht angezeigt. Der Benutzer bemerkt den Fehler entweder nicht oder sieht eine Nachricht und verwendet die Anwendung weiter.
Ein nicht-fataler Fehler lässt dem Programm immer einen Weg zur Wiederherstellung. Der Fehlerbehandler kann alternative Daten bereitstellen, den Vorgang wiederholen oder einen Platzhalter in der Benutzeroberfläche anzeigen. Das Hauptziel ist es, einen Absturz zu verhindern und eine akzeptable Benutzererfahrung aufrechtzuerhalten. Der Entwickler muss in jedem catch-Block explizit ein Wiederherstellungsszenario vorsehen.
Laut Instabug 2024 deinstallieren 65 % der Benutzer eine App nach zwei fehlgeschlagenen Interaktionen. Unbehandelte nicht-fatale Fehler sammeln sich an und beeinträchtigen die Gesamtqualität. Die systematische Protokollierung und Behebung nicht-fataler Fehler ist ein direkter Weg zur Verbesserung der Benutzerbindung und der Bewertungen in den App-Stores.
Netzwerkfehler sind die häufigste Art nicht-fataler Fehler in mobilen Anwendungen. Verbindungszeitüberschreitung, Netzwerkverlust, falscher Server-Statuscode — all diese Situationen werden ohne Absturz abgefangen und behandelt. Dem Benutzer wird eine Nachricht über die Nichtverfügbarkeit des Dienstes mit der Möglichkeit zum Wiederholen angezeigt. Das Wiederholungsmuster mit exponentiellem Backoff ist typisch für Netzwerkfehler.
Falsches Serverantwortformat, fehlendes Pflichtfeld, ungültiger Datentyp — Parsing-Fehler sind nicht-fatal, wenn die Anwendung fehlerhafte Daten korrekt behandelt. Der typische Ansatz besteht darin, Standardfallbackwerte zu verwenden und den Parsing-Fehler mit dem Anforderungskontext für eine spätere serverseitige Analyse zu protokollieren.
Bildladeprobleme, falsche Schriftarten, Layoutfehler — alle sind nicht-fatal, beeinträchtigen jedoch die Benutzererfahrung. Platzhalterbilder und Fallback-Werte helfen, leere Bildschirme zu vermeiden und Fehler weniger sichtbar zu machen. In React Native wird Error Boundary für UI-Fehler mit der Anzeige einer Fallback-Komponente verwendet.
Berechnungsfehler, Zustandsinkonsistenzen, falsche Bildschirmübergänge — Logikfehler führen oft nicht zu einem Absturz, sondern zu fehlerhaftem Anwendungsverhalten. Sie sind ohne systematische Protokollierung und Überwachung schwer zu erkennen, da sie keinen Absturzbericht erzeugen und bis zu einer Benutzerbeschwerde unbemerkt bleiben.
Non-Fatal Error unterscheidet sich vom fatalen Fehler dadurch, dass er dem Programm eine Chance lässt, weiterzuarbeiten. Ein fataler Fehler ist ein Zustand, von dem sich die Anwendung nicht erholen kann: Nullzeiger-Dereferenzierung, Stapelüberlauf, Speichermangel. Ein nicht-fataler Fehler kann abgefangen, behandelt und die Ausführung fortgesetzt werden, während ein fataler Fehler einen Neustart der Anwendung erfordert.
| Eigenschaft | Non-Fatal Error | Fatal Error |
|---|---|---|
| App-Beendigung | Nein | Ja |
| Wiederherstellung möglich | Ja, über catch-Block | Nein |
| Protokollierung | Aus Code über recordException | Nur durch Crash-Reporter |
| UX-Auswirkung | Vorübergehende Unannehmlichkeit | Vollständiger Sitzungsausfall |
| Beispiel | Netzwerk-Timeout, Parse-Fehler | NullPointerException, OOM |
Die Grenze zwischen nicht-fatal und fatal kann von der Implementierung abhängen. Ein Netzwerk-Timeout wird in einer Anwendung als nicht-fatal behandelt (Wiederholung nach 1–2 Sekunden), in einer anderen kann es fatal sein (Absturz, wenn kein Handler vorhanden ist). Eine qualitativ hochwertige Fehlerbehandlung verwandelt potenziell fatale Situationen in nicht-fatale und erhöht die Stabilität der Anwendung. Das Entwerfen eines Fehlerbehandlungssystems ist eine der wichtigsten architektonischen Aufgaben bei der Entwicklung einer mobilen Anwendung mit hohen Zuverlässigkeitsanforderungen. Ein integriertes Überwachungssystem ermöglicht es dem Team, nicht-fatale Fehler schnell zu erkennen und zu beheben, bevor sie eine große Anzahl von Benutzern betreffen.
Firebase Crashlytics ist das wichtigste Werkzeug zur Protokollierung nicht-fataler Fehler in mobilen Anwendungen. Die Methode recordException ermöglicht es, eine nicht-fatale Ausnahme mit vollständigem Stacktrace und Ausführungskontext zu erfassen, ohne die Anwendung zu unterbrechen. Im Gegensatz zu Absturzberichten kann recordException überall im Code aufgerufen werden, um abgefangene Ausnahmen zu protokollieren.
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: Fallback-Daten verwenden
Crashlytics.recordException(e)
showFallbackContent()
}
}
// Protokollierung mit benutzerdefinierten Schlüsseln
Crashlytics.setCustomKey("screen", "Profile")
Crashlytics.setCustomKey("api_version", "v3")
Sentry ist eine Alternative zu Crashlytics mit detaillierterer Diagnose für nicht-fatale Fehler. Das Sentry SDK bietet die Methode captureException, die Ausnahmedetails an den Server sendet. Der Hauptvorteil von Sentry ist die Gruppierung ähnlicher nicht-fataler Fehler in einem einzigen Issue, die Analyse der Wiederholungshäufigkeit und die Bereitstellung des Ausführungskontexts als Breadcrumbs — die Reihenfolge der Benutzeraktionen vor dem Fehler.
Nicht alle nicht-fatalen Fehler müssen protokolliert werden. Erwartete Zustände — Netzwerkfehler bei fehlender Verbindung — können selektiv protokolliert werden. Unerwartete Fehler — NullPointerException in behandeltem Code, ungültiges Datenformat, Logikfehler — sollten immer protokolliert werden. Jedes Team definiert seine eigene Bedeutungsschwelle: Im Durchschnitt gelten 10 bis 20 eindeutige nicht-fatale Fehler pro 1000 Benutzer pro Tag als normal. Es ist wichtig, Warnungen für einen starken Anstieg nicht-fataler Fehler einzurichten — dies kann auf Probleme mit einer neuen API-Version oder eine Regression nach einem Release hinweisen.
Der grundlegende Behandlungsmechanismus ist try-catch, der die Ausnahme abfängt und Wiederherstellungscode ausführt. Für Netzwerkoperationen ist das typische Muster die Wiederholung mit exponentiellem Backoff. Für Parsing-Fehler besteht der Ansatz darin, Standardfallbackwerte zu verwenden und den Kontext für die spätere serverseitige Analyse zu protokollieren.
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)
}
Result-Typen — ein alternativer Ansatz ohne Ausnahmen. Eine Funktion gibt eine versiegelte Klasse Result mit den Varianten Success und Failure zurück. Der aufrufende Code behandelt beide Varianten explizit, sodass keine unbehandelten Fehler übrig bleiben. Result-Typen sind in Kotlin (Result
Für jede Art von nicht-fatalem Fehler sollte eine Wiederherstellungsstrategie geplant werden: Laden zwischengespeicherter Daten bei einem Netzwerkfehler, Verwenden von Standardwerten bei einem Parsing-Fehler, erneutes Initialisieren einer Komponente bei einem UI-Fehler. Eine bewährte Praxis ist es, dem Benutzer einen Toast oder Snackbar mit einer Fehlermeldung anzuzeigen, ohne die Interaktion mit der Anwendung vollständig zu blockieren. Es ist wichtig, zwischen behebbaren und nicht behebbaren Fehlern zu unterscheiden — für letztere ist die Wiederherstellungsstrategie anders, z. B. der Vorschlag, den Bildschirm neu zu starten oder Daten zu löschen. Das Zwischenspeichern des vorherigen erfolgreichen Zustands ist oft der einfachste und effektivste Weg, um nicht-fatale Fehler auf mobilen Plattformen zu behandeln.
Häufig gestellte Fragen
Warnung ist ein Hinweis des Compilers oder statischen Analysators auf ein potenzielles Problem im Code. Ein nicht-fataler Fehler ist eine Laufzeitausnahme, die bereits aufgetreten ist, aber keinen Absturz verursacht hat. Eine Warnung kann vor der Kompilierung behoben werden; ein nicht-fataler Fehler muss während der Ausführung über einen catch-Block behandelt werden.
Nein, eine übermäßige Protokollierung verstopft die Überwachung. Unerwartete Fehler in der Produktion sollten protokolliert werden, während erwartete Zustände ignoriert werden sollten: Netzwerkfehler bei fehlender Verbindung können selektiv protokolliert werden, aber ein NullPointerException in behandeltem Code sollte immer protokolliert werden. Jedes Team definiert seine Bedeutungsschwelle basierend auf dem Anwendungskontext.
In SwiftUI wird ObservableObject mit einem @Published errorState-Feld verwendet, um den Fehlerzustand zu verfolgen. Die View abonniert Änderungen und zeigt alternativen Inhalt an. Vor iOS 17 wurde Combine mit Handlern verwendet; ab iOS 17 werden SwiftData und @Observable-Makros für reaktive UI-Updates verwendet.
Ja, wenn der Fehler eine Kettenreaktion auslöst. Beispiel: Ein nicht-fataler Bildladefehler kann zu einem fehlerhaften UI-Zustand führen, der dann beim Versuch der Anzeige einen Absturz verursacht. Eine qualitativ hochwertige Behandlung nicht-fataler Fehler auf jeder Ebene verhindert deren Eskalation auf eine fatale Ebene.
Unter iOS werden nicht-fatale Fehler über do-catch mit throw behandelt, unter Android über try-catch mit Ausnahmen. iOS verwendet NSError mit Domänen und Fehlercodes, Android verwendet Java/Kotlin-Ausnahmen. Crashlytics funktioniert auf beiden Plattformen identisch über recordException und bietet eine einheitliche Überwachungsschnittstelle.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch