multiversx_sc_wasm_adapter/
panic.rs

1use crate::api::VmApiImpl;
2pub use alloc::alloc::Layout;
3use multiversx_sc::{
4    api::{ErrorApi, ErrorApiImpl},
5    types::{ManagedBuffer, ManagedType},
6};
7
8/// Also used in wasm crate macros.
9pub use core::panic::PanicInfo;
10
11/// Default panic handler for all contracts.
12pub fn panic_fmt(_: &PanicInfo) -> ! {
13    crate::error_hook::signal_error(multiversx_sc::err_msg::PANIC_OCCURRED.as_bytes())
14}
15
16/// Panic handler that formats and sends the original message.
17///
18/// Mostly used for debugging, the additional code is normally not deemed to be worth it.
19pub fn panic_fmt_with_message(panic_info: &PanicInfo) -> ! {
20    let mut panic_msg = ManagedPanicMessage::default();
21    panic_msg.append_str("panic occurred: ");
22
23    core::fmt::write(&mut panic_msg, format_args!("{panic_info}"))
24        .unwrap_or_else(|_| panic_msg.append_str("unable to write panic"));
25
26    signal_error_with_managed_panic_message(panic_msg)
27}
28
29pub fn signal_error_with_managed_panic_message(panic_msg: ManagedPanicMessage) -> ! {
30    VmApiImpl::error_api_impl().signal_error_from_buffer(panic_msg.buffer.get_handle())
31}
32
33#[derive(Default)]
34pub struct ManagedPanicMessage {
35    buffer: ManagedBuffer<VmApiImpl>,
36}
37
38impl ManagedPanicMessage {
39    pub fn append_str(&mut self, s: &str) {
40        self.buffer.append_bytes(s.as_bytes());
41    }
42}
43
44impl core::fmt::Write for ManagedPanicMessage {
45    fn write_str(&mut self, s: &str) -> core::fmt::Result {
46        let file_name = match s.rfind('/') {
47            Some(index) => &s[index + 1..],
48            None => s,
49        };
50        self.append_str(file_name);
51        Ok(())
52    }
53}