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
UserDataBorrowMutError,
/// A Rust callback returned `Err`, raising the contained `Error` as a Lua error.
///
/// The first field is the Lua traceback, the second field holds the original error.
CallbackError(String, Arc<Error>),
CallbackError {
/// Lua call stack backtrace.
traceback: String,
/// Original error returned by the Rust code.
cause: Arc<Error>,
},
/// A custom error.
///
/// 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::UserDataBorrowError => write!(fmt, "Userdata already mutably 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),
}
}
@ -148,14 +151,14 @@ impl StdError for Error {
Error::UserDataTypeMismatch => "lua userdata type mismatch",
Error::UserDataBorrowError => "lua userdata already mutably borrowed",
Error::UserDataBorrowMutError => "lua userdata already borrowed",
Error::CallbackError(_, _) => "lua callback error",
Error::CallbackError { ref cause, .. } => cause.description(),
Error::ExternalError(ref err) => err.description(),
}
}
fn cause(&self) -> Option<&StdError> {
match *self {
Error::CallbackError(_, ref cause) => Some(cause.as_ref()),
Error::CallbackError { ref cause, .. } => Some(cause.as_ref()),
Error::ExternalError(ref err) => err.cause(),
_ => None,
}

View File

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

View File

@ -380,7 +380,10 @@ pub unsafe fn pcall_with_traceback(
.to_str()
.unwrap_or_else(|_| "<could not capture traceback>")
.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);
} else if !is_wrapped_panic(state, 1) {
let s = ffi::lua_tolstring(state, 1, ptr::null_mut());
@ -415,7 +418,10 @@ pub unsafe fn resume_with_traceback(
.to_str()
.unwrap_or_else(|_| "<could not capture traceback>")
.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);
} else if !is_wrapped_panic(state, 1) {
let s = ffi::lua_tolstring(state, 1, ptr::null_mut());