Tracks
/
Cairo
Cairo
/
Lehrplan
/
Fehlerbehandlung
Fe

Fehlerbehandlung in Cairo

1 Übung

Über Fehlerbehandlung

Cairo bietet Techniken zur Fehlerbehandlung, mit denen du Probleme angehst und Fehler verwaltest, damit der Code während der Ausführung reibungslos läuft.

In Cairo gibt es zwei Arten von Fehlern:

  • Unbehebbare Fehler mit panic: Diese Fehler beenden das Programm sofort.
  • Behebbare Fehler mit Result: Diese Fehler kannst du während der Laufzeit behandeln.

Unbehebbare Fehler mit panic

In Cairo können während der Programmausführung unerwartete Probleme auftreten, die zu Laufzeitfehlern führen, den sogenannten „Panics“. Das stoppt die Programmausführung, was hilfreich ist, wenn eine Fortsetzung keinen Sinn ergeben würde. Ein Panic kann entweder unbeabsichtigt auftreten, durch Aktionen, die den Code zum Panic bringen (z. B. der Zugriff auf ein Array außerhalb seiner Grenzen), oder absichtlich, indem du die Funktion panic aufrufst.

fn main() {
    let data = array![1, 2];

    if true {
        panic(data);
    }
    println!("This line will not be reached.");
}

Wenn du dieses Beispiel ausführst, wird Folgendes in der Konsole ausgegeben:

Run panicked with [1, 2, ].

Es gibt außerdem ein spezielles Makro namens panic!, mit dem ein ByteArray als Fehlermeldung verwendet werden kann.

panic!("The error for the panic! Error message is not limited to 31 characters anymore");

Das assert!-Makro

Das Makro assert! ist ein nützliches Werkzeug, um bestimmte Bedingungen in deinem Code durchzusetzen. Wenn die Bedingung in assert! false ergibt, löst das Programm einen Panic mit einer ByteArray-Fehlermeldung aus. Das wird oft verwendet, um Annahmen während der Entwicklung zu überprüfen und sicherzustellen, dass Werte bestimmte Kriterien erfüllen.

Zum Beispiel:

fn main() {
    let x = 5;
    assert!(x > 0, "x must be greater than zero");
}

Wenn x nicht größer als null ist, löst das Programm einen Panic mit der Meldung "x must be greater than zero" aus. assert! ist hilfreich, um Invarianten und Vorbedingungen zu prüfen, ohne manuell Fehlerbehandlungscode zu schreiben.

Die nopanic-Notation

Die nopanic-Notation in Cairo zeigt an, dass eine Funktion niemals einen Panic auslöst.

fn function_never_panic() -> felt252 nopanic {
    108
}

Eine nopanic-Funktion kann nur in einer Funktion aufgerufen werden, die ebenfalls als nopanic gekennzeichnet ist.

Das panic_with-Attribut

Das panic_with-Attribut in Cairo markiert eine Funktion, die ein Option oder Result zurückgibt, und erstellt einen Wrapper für deine gekennzeichnete Funktion, der einen Panic auslöst, wenn die Funktion Option::None oder Result::Err zurückgibt.

#[panic_with('value is 0', wrap_not_zero)]
fn check_not_zero(value: u128) -> Option<u128> {
    if value == 0 {
        Option::None
    } else {
        Option::Some(value)
    }
}

fn main() {
    check_not_zero(0); // -> returns Option::None
    wrap_not_zero(0);  // -> panics with 'value is 0'
}

Behebbare Fehler mit Result

Das Enum Result behandelt Fehler auf elegante Weise und gibt Feedback, statt abzustürzen oder undefiniertes Verhalten zu erzeugen.

enum Result<T, E> {
    Ok: T,
    Err: E,
}

Schauen wir uns ein Beispiel an, wie wir dieses Enum verwenden können, um eine Division durch null zu behandeln:

fn divide(a: u32, b: u32) -> Result<u32, ByteArray> {
    if b == 0 {
        return Result::Err("Error: Division by zero"); // Return an error if division by zero is attempted
    }
    Result::Ok(a / b)
}

fn main() {
    // Test with division by zero
    match divide(10, 0) {
        Result::Ok(result) => println!("Division successful: {}", result),
        Result::Err(e) => println!("{}", e),
    }
}

Der ?-Operator

Der ?-Operator wird für eine prägnante und implizite Fehlerbehandlung verwendet und überlässt der aufrufenden Funktion den Umgang mit allen Fehlern, die auftreten könnten. Wenn du den ?-Operator auf einen Typ Result oder Option anwendest, macht er Folgendes:

  • Wenn der Wert Result::Ok(x) oder Option::Some(x) ist, gibt er den inneren Wert x direkt zurück.
  • Wenn der Wert Result::Err(e) oder Option::None ist, gibt er den Fehler oder None weiter, indem er sofort aus der Funktion zurückkehrt.
fn parse_u8(s: felt252) -> Result<u8, felt252> {
    match s.try_into() {
        Option::Some(value) => Result::Ok(value),
        Option::None => Result::Err('Invalid integer'),
    }
}

fn do_something_with_parse_u8(input: felt252) -> Result<u8, felt252> {
    let input_to_u8: u8 = parse_u8(input)?;
    // DO SOMETHING
    let res = input_to_u8 - 1;
    Result::Ok(res)
}

fn main() {
    let number: felt252 = 258;
    match do_something_with_parse_u8(number) {
        Result::Ok(value) => println!("Result: {}", value),
        Result::Err(e) => println!("Error: {}", e),
    }
}
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab

Lerne Fehlerbehandlung

Das Üben ist gesperrt

Schalte 1 weitere Übung frei, um Fehlerbehandlung zu üben