====== Lyx – Fehlerbehandlung (Exception Handling) ====== Lyx bietet zwei primäre Mechanismen zum Umgang mit Fehlern: Das klassische **Exception-Handling** für allgemeine Anwendungen und das **Result-Pattern** für deterministische, sicherheitskritische Systeme. ===== 1. Natives Try-Catch-System ===== Lyx nutzt ein Zero-Cost-Exception-Modell. Das bedeutet, dass im Gut-Fall (kein Fehler) keine Performance-Einbußen entstehen. fn read_config(path: pchar) { try { var file := open_file(path); // ... Logik ... } catch (e: FileException) { PrintStr("Dateifehler: "); PrintStr(e.message); } catch { PrintStr("Ein unbekannter Fehler ist aufgetreten."); } } * **try**: Markiert den Block, der überwacht werden soll. * **catch (e: Type)**: Fängt spezifische Fehlerklassen ab. * **throw**: Löst eine Exception aus. [Image of exception handling flow chart] ===== 2. Fehler auslösen (throw & panic) ===== Es gibt zwei Wege, einen kritischen Zustand zu signalisieren: * **throw**: Wird für erwartbare Fehler genutzt (z. B. "Datei nicht gefunden"). Die Funktion bricht ab, bis ein passender ''catch''-Block gefunden wird. * **panic**: Wird für nicht abfangbare, katastrophale Fehler genutzt (z. B. "Division durch Null" oder "Hardware-Defekt"). Ein ''panic'' beendet das Programm sofort sicherheitshalber. fn divide(a: int, b: int): int { if (b == 0) { panic("Division by zero in flight-critical section!"); } return a / b; } ===== 3. Das Result-Pattern (Aerospace-Standard) ===== In Projekten mit **DO-178C DAL A** Zertifizierung ist die Verwendung von ''throw'' oft untersagt, da der Sprungpunkt zur Compile-Zeit schwer zu berechnen ist (**WCET-Problematik**). Stattdessen wird das ''Result''-Pattern verwendet. ^ Methode ^ Kontrollfluss ^ Zertifizierbarkeit ^ | **Exceptions** | Springt (unvorhersehbar) | Schwierig (DAL C/D) | | **Result-Typ** | Linear (explizit) | Exzellent (DAL A/B) | ==== Beispiel mit Result-Typ ==== import std.errors; fn calculate_heading(): Result { if (gyro_failed()) { return Error("Gyroscope Timeout"); } return Ok(180.0); } // Aufruf: var res := calculate_heading(); match (res) { case Ok(val) => { update_ui(val); } case Error(e) => { handle_error(e); } } ===== 4. Resource Cleanup (finally-Ersatz) ===== Lyx verzichtet auf ein explizites ''finally''-Keyword zugunsten des **RAII**-Prinzips (Resource Allocation Is Initialization) oder Smart-Pointern (ab v0.6.x). Es wird empfohlen, Ressourcen über Klassen-Destruktoren freizugeben, die automatisch aufgerufen werden, wenn der Scope verlassen wird – auch im Falle einer Exception. ===== 5. Best Practices ===== * **Spezifisch fangen**: Fange immer den spezifischsten Fehlertyp ab, nicht einfach nur ''any''. * **Keine leeren Catch-Blöcke**: Verschlucke Fehler niemals ohne Logging oder Reaktion. * **DAL A/B Regel**: Nutze in flugkritischen Schleifen ausschließlich ''Result''-Typen oder ''panic'', niemals ''try-catch''.