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.
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.");
}
}
[Image of exception handling flow chart]
Es gibt zwei Wege, einen kritischen Zustand zu signalisieren:
catch-Block gefunden wird.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;
}
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) |
import std.errors;
fn calculate_heading(): Result<f64, Error> {
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); }
}
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.
any.Result-Typen oder panic, niemals try-catch.