vm_error.rs
1 // Copyright (c) 2025 ADnet Contributors 2 // This file is part of the AlphaVM library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 pub use std::error::Error; 17 18 /// This macro provides a VM runtime environment which will safely halt 19 /// without producing logs that look like unexpected behavior. 20 /// In debug mode, it prints to stderr using the format: "VM safely halted at {location}: {halt message}". 21 #[macro_export] 22 macro_rules! try_vm_runtime { 23 ($e:expr) => {{ 24 use std::panic; 25 26 // Store the previous hook (if any). 27 let previous_hook = panic::take_hook(); 28 29 // Set a custom hook before calling catch_unwind to 30 // indicate that the panic was expected and handled. 31 panic::set_hook(Box::new(|err| { 32 #[cfg(debug_assertions)] 33 { 34 // Remove all words up to "panicked". 35 let trimmed = err 36 .to_string() 37 .split_ascii_whitespace() 38 .skip_while(|&word| word != "panicked") 39 .collect::<Vec<&str>>() 40 .join(" "); 41 42 // Have the message start with "VM safely halted". 43 let msg = trimmed.replacen("panicked", "VM safely halted", 1); 44 eprintln!("{msg}"); 45 } 46 })); 47 48 // Perform the operation that may panic. 49 let result = panic::catch_unwind(panic::AssertUnwindSafe($e)); 50 51 // Restore the standard panic hook. 52 panic::set_hook(previous_hook); 53 54 // Return the result, allowing regular error-handling. 55 result 56 }}; 57 }