Διαδρομές
/
Cairo
Cairo
/
Ύλη
/
Διαχείριση Σφαλμάτων
Δι

Διαχείριση Σφαλμάτων σε Cairo

1 άσκηση

Σχετικά με την έννοια Διαχείριση Σφαλμάτων

Η Cairo παρέχει τεχνικές διαχείρισης σφαλμάτων για την αντιμετώπιση προβλημάτων και τη διαχείριση σφαλμάτων, επιτρέποντας την ομαλή εκτέλεση του κώδικα.

Υπάρχουν δύο τύποι σφαλμάτων στην Cairo:

  • Μη ανακτήσιμα σφάλματα με panic: αυτά τα σφάλματα τερματίζουν το πρόγραμμα αμέσως.
  • Ανακτήσιμα σφάλματα με Result: αυτά τα σφάλματα μπορούν να αντιμετωπιστούν κατά τη διάρκεια της εκτέλεσης.

Μη ανακτήσιμα σφάλματα με panic

Στην Cairo, κατά την εκτέλεση του προγράμματος μπορεί να προκύψουν απρόσμενα προβλήματα, που οδηγούν σε σφάλματα χρόνου εκτέλεσης, τα λεγόμενα "panics". Αυτό σταματά την εκτέλεση του προγράμματος, κάτι που βοηθά στην περίπτωση όπου η συνέχεια δεν θα είχε κανένα νόημα. Ένα panic μπορεί να συμβεί είτε άθελά μας, μέσα από ενέργειες που προκαλούν το panic του κώδικα (π.χ. η πρόσβαση σε έναν πίνακα πέρα από τα όρια του), είτε σκόπιμα, καλώντας τη συνάρτηση panic.

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

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

Η εκτέλεση αυτού του παραδείγματος θα εκτυπώσει τα εξής στην κονσόλα:

Run panicked with [1, 2, ].

Υπάρχει επίσης μια ειδική μακροεντολή, η panic!, που επιτρέπει να χρησιμοποιηθεί ένα ByteArray ως μήνυμα σφάλματος.

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

Η μακροεντολή assert!

Η μακροεντολή assert! είναι ένα χρήσιμο εργαλείο για να επιβάλλεις συγκεκριμένες συνθήκες στον κώδικά σου. Αν η συνθήκη στο assert! αξιολογηθεί σε false, το πρόγραμμα θα προκαλέσει panic με ένα μήνυμα σφάλματος ByteArray. Αυτό χρησιμοποιείται συχνά για να επαληθεύεις υποθέσεις κατά την ανάπτυξη και να διασφαλίζεις ότι οι τιμές πληρούν ορισμένα κριτήρια.

Για παράδειγμα:

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

Αν το x δεν είναι μεγαλύτερο από το μηδέν, το πρόγραμμα θα προκαλέσει panic με το μήνυμα "x must be greater than zero". Η assert! είναι χρήσιμη για τον έλεγχο αναλλοίωτων συνθηκών και προϋποθέσεων χωρίς να γράφεις χειροκίνητα κώδικα διαχείρισης σφαλμάτων.

Ο συμβολισμός nopanic

Ο συμβολισμός nopanic της Cairo δηλώνει ότι μια συνάρτηση δεν θα προκαλέσει ποτέ panic.

fn function_never_panic() -> felt252 nopanic {
    108
}

Μια συνάρτηση nopanic μπορεί να κληθεί μόνο μέσα από μια συνάρτηση που είναι επίσης επισημασμένη ως nopanic.

Το χαρακτηριστικό panic_with

Το χαρακτηριστικό panic_with της Cairo χρησιμοποιείται για να επισημάνει μια συνάρτηση που επιστρέφει Option ή Result, και δημιουργεί ένα περιτύλιγμα για τη συνάρτηση που έχεις επισημάνει, το οποίο θα προκαλέσει panic αν η συνάρτηση επιστρέψει Option::None ή Result::Err.

#[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'
}

Ανακτήσιμα σφάλματα με Result

Το enum Result χειρίζεται τα σφάλματα με κομψό τρόπο, παρέχοντας ανατροφοδότηση αντί να καταρρέει ή να παράγει απροσδιόριστη συμπεριφορά.

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

Ας δούμε ένα παράδειγμα για το πώς θα μπορούσαμε να χρησιμοποιήσουμε αυτό το enum για να χειριστούμε μια διαίρεση με το μηδέν:

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),
    }
}

Ο τελεστής ?

Ο τελεστής ? χρησιμοποιείται για συνοπτική και έμμεση διαχείριση σφαλμάτων, αφήνοντας τη συνάρτηση που καλεί να αντιμετωπίσει τυχόν σφάλματα που μπορεί να προκύψουν. Όταν χρησιμοποιείς τον τελεστή ? σε έναν τύπο Result ή Option, κάνει τα εξής:

  • Αν η τιμή είναι Result::Ok(x) ή Option::Some(x), επιστρέφει απευθείας την εσωτερική τιμή x.
  • Αν η τιμή είναι Result::Err(e) ή Option::None, διαδίδει το σφάλμα ή το None επιστρέφοντας αμέσως από τη συνάρτηση.
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),
    }
}
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα

Μάθε την έννοια Διαχείριση Σφαλμάτων

Η εξάσκηση είναι κλειδωμένη

Ξεκλείδωσε 1 ακόμη άσκηση για να εξασκηθείς στην έννοια Διαχείριση Σφαλμάτων