Fix handling of `CallbackError`

Previously, the traceback would be printed, but not the actual error.

I've removed traceback printing completely, not sure if that's a good
idea. A `Display` impl that outputs multiple lines feels weird.
This commit is contained in:
Jonas Schievink 2017-08-01 19:46:05 +02:00
parent 7e250dacce
commit ed0565c176
3 changed files with 18 additions and 9 deletions

View File

@ -83,9 +83,12 @@ pub enum Error {
/// [`UserData`]: trait.UserData.html /// [`UserData`]: trait.UserData.html
UserDataBorrowMutError, UserDataBorrowMutError,
/// A Rust callback returned `Err`, raising the contained `Error` as a Lua error. /// A Rust callback returned `Err`, raising the contained `Error` as a Lua error.
/// CallbackError {
/// The first field is the Lua traceback, the second field holds the original error. /// Lua call stack backtrace.
CallbackError(String, Arc<Error>), traceback: String,
/// Original error returned by the Rust code.
cause: Arc<Error>,
},
/// A custom error. /// A custom error.
/// ///
/// This can be used for returning user-defined errors from callbacks. /// This can be used for returning user-defined errors from callbacks.
@ -129,7 +132,7 @@ impl fmt::Display for Error {
Error::UserDataTypeMismatch => write!(fmt, "Userdata not expected type"), Error::UserDataTypeMismatch => write!(fmt, "Userdata not expected type"),
Error::UserDataBorrowError => write!(fmt, "Userdata already mutably borrowed"), Error::UserDataBorrowError => write!(fmt, "Userdata already mutably borrowed"),
Error::UserDataBorrowMutError => write!(fmt, "Userdata already borrowed"), Error::UserDataBorrowMutError => write!(fmt, "Userdata already borrowed"),
Error::CallbackError(ref msg, _) => write!(fmt, "Error during lua callback: {}", msg), Error::CallbackError { ref cause, .. } => write!(fmt, "{}", cause),
Error::ExternalError(ref err) => err.fmt(fmt), Error::ExternalError(ref err) => err.fmt(fmt),
} }
} }
@ -148,14 +151,14 @@ impl StdError for Error {
Error::UserDataTypeMismatch => "lua userdata type mismatch", Error::UserDataTypeMismatch => "lua userdata type mismatch",
Error::UserDataBorrowError => "lua userdata already mutably borrowed", Error::UserDataBorrowError => "lua userdata already mutably borrowed",
Error::UserDataBorrowMutError => "lua userdata already borrowed", Error::UserDataBorrowMutError => "lua userdata already borrowed",
Error::CallbackError(_, _) => "lua callback error", Error::CallbackError { ref cause, .. } => cause.description(),
Error::ExternalError(ref err) => err.description(), Error::ExternalError(ref err) => err.description(),
} }
} }
fn cause(&self) -> Option<&StdError> { fn cause(&self) -> Option<&StdError> {
match *self { match *self {
Error::CallbackError(_, ref cause) => Some(cause.as_ref()), Error::CallbackError { ref cause, .. } => Some(cause.as_ref()),
Error::ExternalError(ref err) => err.cause(), Error::ExternalError(ref err) => err.cause(),
_ => None, _ => None,
} }

View File

@ -501,7 +501,7 @@ fn test_error() {
_ => panic!("error not returned"), _ => panic!("error not returned"),
} }
match rust_error.call::<_, ()>(()) { match rust_error.call::<_, ()>(()) {
Err(Error::CallbackError(_, _)) => {} Err(Error::CallbackError { .. }) => {}
Err(_) => panic!("error is not CallbackError kind"), Err(_) => panic!("error is not CallbackError kind"),
_ => panic!("error not returned"), _ => panic!("error not returned"),
} }

View File

@ -380,7 +380,10 @@ pub unsafe fn pcall_with_traceback(
.to_str() .to_str()
.unwrap_or_else(|_| "<could not capture traceback>") .unwrap_or_else(|_| "<could not capture traceback>")
.to_owned(); .to_owned();
push_wrapped_error(state, Error::CallbackError(traceback, Arc::new(error))); push_wrapped_error(state, Error::CallbackError {
traceback,
cause: Arc::new(error),
});
ffi::lua_remove(state, -2); ffi::lua_remove(state, -2);
} else if !is_wrapped_panic(state, 1) { } else if !is_wrapped_panic(state, 1) {
let s = ffi::lua_tolstring(state, 1, ptr::null_mut()); let s = ffi::lua_tolstring(state, 1, ptr::null_mut());
@ -415,7 +418,10 @@ pub unsafe fn resume_with_traceback(
.to_str() .to_str()
.unwrap_or_else(|_| "<could not capture traceback>") .unwrap_or_else(|_| "<could not capture traceback>")
.to_owned(); .to_owned();
push_wrapped_error(state, Error::CallbackError(traceback, Arc::new(error))); push_wrapped_error(state, Error::CallbackError {
traceback,
cause: Arc::new(error),
});
ffi::lua_remove(state, -2); ffi::lua_remove(state, -2);
} else if !is_wrapped_panic(state, 1) { } else if !is_wrapped_panic(state, 1) {
let s = ffi::lua_tolstring(state, 1, ptr::null_mut()); let s = ffi::lua_tolstring(state, 1, ptr::null_mut());