Skip to main content

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}