capypad
0 Tage Serie
rust / intermediate
Snippet

Panic Behandlung mit std::panic::catch_unwind

catch_unwind fängt Panics ab und konvertiert sie in Result-Werte, was Wiederherstellung aus Panic-Zuständen ermöglicht. Dies ist essentiell beim Implementieren von Plugins, Foreign Function Interfaces oder async Runtimes. AssertUnwindSafe ist ein Helfer für Closures, bei denen der Programmierer garantiert, dass sie sicher unwinden können.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use std::panic::{catch_unwind, AssertUnwindSafe};
 
fn risky_operation(divisor: i32) -> i32 {
100 / divisor // Will panic if divisor is 0
}
 
fn main() {
// Successful case
let result = catch_unwind(|| {
risky_operation(10)
});
 
match result {
Ok(value) => println!("Calculation succeeded: {}", value),
Err(e) => println!("Panic occurred: {:?}", e),
}
 
// Panic case - divisor is 0
let panic_result = catch_unwind(|| {
risky_operation(0)
});
 
if panic_result.is_err() {
println!("Caught panic from division by zero!");
}
 
// Using AssertUnwindSafe for shared references
let shared_data = vec![1, 2, 3];
let safe_result = catch_unwind(AssertUnwindSafe(|| {
println!("Processing: {:?}", shared_data);
42
}));
 
println!("Safe result: {:?}", safe_result);
 
// Practical example: recoverable parsing
let numbers = vec!["10", "20", "oops", "40"];
for num_str in numbers {
let parsed = catch_unwind(|| num_str.parse::<i32>().unwrap());
match parsed {
Ok(n) => println!("Parsed: {}", n),
Err(_) => println!("Failed to parse '{}', continuing...", num_str),
}
}
}
Erklärung
1
catch_unwind(|| risky_operation(10))
Führt Closure aus und fängt Panics ab, gibt Result<T, Box<dyn Any + Send>> zurück
2
AssertUnwindSafe(|| ... )
Marker-Typ, der garantiert dass Closure sicher unwinden kann - verwende wenn du weißt dass die Closure keine Invarianten verletzt
3
Ok(value) => println!("{}", value)
Normale Beendigung - kein Panic in der Closure aufgetreten
4
Err(e) => println!("{:?}", e)
Panic wurde gefangen - e enthält Panic-Payload-Informationen