android_activity/
error.rs

1use thiserror::Error;
2
3#[derive(Error, Debug)]
4pub enum AppError {
5    #[error("Operation only supported from the android_main() thread: {0}")]
6    NonMainThread(String),
7
8    #[error("Java VM or JNI error, including Java exceptions")]
9    JavaError(String),
10
11    #[error("Input unavailable")]
12    InputUnavailable,
13}
14
15pub type Result<T> = std::result::Result<T, AppError>;
16
17// XXX: we don't want to expose jni-rs in the public API
18// so we have an internal error type that we can generally
19// use in the backends and then we can strip the error
20// in the frontend of the API.
21//
22// This way we avoid exposing a public trait implementation for
23// `From<jni::errors::Error>`
24#[derive(Error, Debug)]
25pub(crate) enum InternalAppError {
26    #[error("A JNI error")]
27    JniError(jni::errors::JniError),
28    #[error("A Java Exception was thrown via a JNI method call")]
29    JniException(String),
30    #[error("A Java VM error")]
31    JvmError(jni::errors::Error),
32    #[error("Input unavailable")]
33    InputUnavailable,
34}
35
36pub(crate) type InternalResult<T> = std::result::Result<T, InternalAppError>;
37
38impl From<jni::errors::Error> for InternalAppError {
39    fn from(value: jni::errors::Error) -> Self {
40        InternalAppError::JvmError(value)
41    }
42}
43impl From<jni::errors::JniError> for InternalAppError {
44    fn from(value: jni::errors::JniError) -> Self {
45        InternalAppError::JniError(value)
46    }
47}
48
49impl From<InternalAppError> for AppError {
50    fn from(value: InternalAppError) -> Self {
51        match value {
52            InternalAppError::JniError(err) => AppError::JavaError(err.to_string()),
53            InternalAppError::JniException(msg) => AppError::JavaError(msg),
54            InternalAppError::JvmError(err) => AppError::JavaError(err.to_string()),
55            InternalAppError::InputUnavailable => AppError::InputUnavailable,
56        }
57    }
58}