low_luajit/lua/error.rs
1use core::{ffi::CStr, hint::unreachable_unchecked};
2use crate::{LuaState, ffi};
3
4/// Error handling functions.
5impl LuaState {
6 /* TODO: Currently this function effectively does nothing for some reason.
7 /// Sets a new panic function, returning the previous one.
8 ///
9 /// `panic_f` will be called when an error happens outside of a protected environment (see [`LuaState::pcall`] and [`LuaState::cpcall`]) before exiting.
10 /// You can avoid exiting by having `panic_f` not return.
11 ///
12 /// When `panic_f` is called, the error message will be at the top of the stack.
13 ///
14 /// The default panic function simply prints the error message.
15 ///
16 /// Note: when running Lua within Rust, errors (treated as panics) might cause an early abort, skipping `panic_f`
17 #[inline]
18 pub fn at_panic(&self, panic_f: CFunction) -> CFunction {
19 unsafe { mem::transmute::<lua_CFunction, CFunction>(ffi::lua_atpanic(self.as_ptr(), mem::transmute::<CFunction, lua_CFunction>(panic_f)))}
20 }*/
21
22 /// Triggers a Lua error using `msg` as the error message (alongside file and line information).
23 ///
24 /// # Lua Errors
25 ///
26 /// This function always errors intentionally.
27 #[inline]
28 pub fn error(&self, msg: &CStr) -> ! {
29 // SAFETY: self.as_ptr() and the two CStrs are always valid and luaL_error never returns.
30 unsafe {
31 ffi::luaL_error(self.as_ptr(), c"%s".as_ptr(), msg.as_ptr());
32 unreachable_unchecked();
33 }
34 }
35
36 /// Triggers a Lua error with the following message (alongside file and line information):
37 ///
38 /// ```text
39 /// bad argument #{arg_n} to '{func}' ({type_name} expected, got {arg_type})
40 /// ```
41 ///
42 /// (`func` is retrieved from the call stack and `arg_type` is the type of the element at index `arg_n`.)
43 ///
44 /// # Lua Errors
45 ///
46 /// This function always errors intentionally.
47 #[inline]
48 pub fn type_error(&self, arg_n: i32, type_name: &CStr) -> ! {
49 // SAFETY: self.as_ptr() and type_name are always valid and luaL_typeerror never returns.
50 unsafe {
51 ffi::luaL_typerror(self.as_ptr(), arg_n, type_name.as_ptr());
52 unreachable_unchecked();
53 }
54 }
55
56 /// Triggers a Lua error with the following message (alongside file and line information):
57 ///
58 /// ```text
59 /// bad argument #{arg_n} to '{func}' ({extra_msg})
60 /// ```
61 ///
62 /// (`func` is retrieved from the call stack.)
63 ///
64 /// # Lua Errors
65 ///
66 /// This function always errors intentionally.
67 #[inline]
68 pub fn arg_error(&self, arg_n: i32, extra_msg: &CStr) -> ! {
69 // SAFETY: self.as_ptr() and extra_msg are always valid and luaL_argerror never returns.
70 unsafe {
71 ffi::luaL_argerror(self.as_ptr(), arg_n, extra_msg.as_ptr());
72 unreachable_unchecked();
73 }
74 }
75
76 /// Pushes onto the stack a string specifying the position of the function at the given `level`:
77 /// level `0` is the current running function, level `1` is the function that called the current running function, and so on.
78 ///
79 /// The pushed string has the following format:
80 ///
81 /// ```text
82 /// chunk_name:current_line:
83 /// ```
84 ///
85 /// *(A space is appended at the end.)*
86 ///
87 /// If the location of the function at the given `level` is unknown, or `level` is invalid, an empty string is pushed instead.
88 #[inline]
89 pub fn location(&mut self, level: i32) {
90 // SAFETY: self.as_ptr() is always valid.
91 unsafe { ffi::luaL_where(self.as_ptr(), level); }
92 }
93
94 /// Triggers a Lua error, popping the top element and using it as the full error message (no file or line information is included).
95 ///
96 /// If the stack is empty, a generic error message is pushed beforehand.
97 ///
98 /// You probably want to use [`LuaState::error`] instead.
99 ///
100 /// # Lua Errors
101 ///
102 /// This function always errors intentionally.
103 #[inline]
104 pub fn raw_error(&mut self) -> ! {
105 if self.get_top() < 1 {
106 self.push_byte_string(b"(no error message specified)");
107 }
108
109 // SAFETY: self.as_ptr() is always valid, lua_error never returns, and the stack is not empty.
110 unsafe {
111 ffi::lua_error(self.as_ptr());
112 unreachable_unchecked();
113 }
114 }
115}