====== 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''.