use Env::exception_catch in clear_and_map_exception_to_err

This simplifies the `clear_and_map_exception_to_err` utility so it's based
on `jni::Env::exception_catch`
This commit is contained in:
Robert Bragg
2026-03-12 20:55:01 +00:00
parent 2a05cd2763
commit 43de2770b9
2 changed files with 4 additions and 47 deletions
-3
View File
@@ -25,8 +25,6 @@ pub type Result<T> = std::result::Result<T, AppError>;
pub(crate) enum InternalAppError {
#[error("A JNI error")]
JniError(jni::errors::JniError),
#[error("A Java Exception was thrown via a JNI method call")]
JniException(String),
// For internal errors that don't lead to a Java exception but are
// still JNI related.
#[error("A bad argument was passed to a JNI method: {0}")]
@@ -54,7 +52,6 @@ impl From<InternalAppError> for AppError {
fn from(value: InternalAppError) -> Self {
match value {
InternalAppError::JniError(err) => AppError::JavaError(err.to_string()),
InternalAppError::JniException(msg) => AppError::JavaError(msg),
InternalAppError::JniBadArgument(msg) => AppError::JavaError(msg),
InternalAppError::JvmError(err) => AppError::JavaError(err.to_string()),
InternalAppError::InputUnavailable => AppError::InputUnavailable,
+4 -44
View File
@@ -7,21 +7,6 @@
use crate::error::InternalAppError;
fn try_get_stack_trace(
env: &mut jni::Env<'_>,
throwable: &jni::objects::JThrowable,
) -> jni::errors::Result<String> {
let stack_trace = throwable.get_stack_trace(env)?;
let len = stack_trace.len(env)?;
let mut trace = String::new();
for i in 0..len {
let element = stack_trace.get_element(env, i)?;
let element_jstr = element.try_to_string(env)?;
trace.push_str(&format!("{i}: {element_jstr}\n"));
}
Ok(trace)
}
/// Use with `.map_err()` to map `jni::errors::Error::JavaException` into a
/// richer error based on the actual contents of the `JThrowable`
///
@@ -34,35 +19,10 @@ pub(crate) fn clear_and_map_exception_to_err(
err: jni::errors::Error,
) -> InternalAppError {
if matches!(err, jni::errors::Error::JavaException) {
let result = env.with_local_frame::<_, _, InternalAppError>(5, |env| {
let Some(e) = env.exception_occurred() else {
// should only be called after receiving a JavaException Result
unreachable!("JNI Error was JavaException but no exception was set");
};
env.exception_clear();
let msg = e.get_message(env)?;
let mut msg: String = msg.to_string();
match try_get_stack_trace(env, &e) {
Ok(stack_trace) => {
msg.push_str("stack trace:\n");
msg.push_str(&stack_trace);
}
Err(err) => {
msg.push_str(&format!("\nfailed to get stack trace: {err:?}"));
}
}
Ok(msg)
});
match result {
Ok(msg) => InternalAppError::JniException(msg),
Err(err) => InternalAppError::JniException(format!(
"UNKNOWN (Failed to query JThrowable: {err:?})"
)),
}
env.exception_catch()
.expect_err("Spurious JavaException error with no exception to catch")
} else {
err.into()
err
}
.into()
}