1#![allow(missing_docs)]
2
3use thiserror::Error;
4
5use crate::sys;
6use crate::wrapper::signature::TypeSignature;
7
8pub type Result<T> = std::result::Result<T, Error>;
9
10#[derive(Debug, Error)]
11pub enum Error {
12 #[error("Invalid JValue type cast: {0}. Actual type: {1}")]
13 WrongJValueType(&'static str, &'static str),
14 #[error("Invalid constructor return type (must be void)")]
15 InvalidCtorReturn,
16 #[error("Invalid number or type of arguments passed to java method: {0}")]
17 InvalidArgList(TypeSignature),
18 #[error("Method not found: {name} {sig}")]
19 MethodNotFound { name: String, sig: String },
20 #[error("Field not found: {name} {sig}")]
21 FieldNotFound { name: String, sig: String },
22 #[error("Java exception was thrown")]
23 JavaException,
24 #[error("JNIEnv null method pointer for {0}")]
25 JNIEnvMethodNotFound(&'static str),
26 #[error("Null pointer in {0}")]
27 NullPtr(&'static str),
28 #[error("Null pointer deref in {0}")]
29 NullDeref(&'static str),
30 #[error("Mutex already locked")]
31 TryLock,
32 #[error("JavaVM null method pointer for {0}")]
33 JavaVMMethodNotFound(&'static str),
34 #[error("Field already set: {0}")]
35 FieldAlreadySet(String),
36 #[error("Throw failed with error code {0}")]
37 ThrowFailed(i32),
38 #[error("Parse failed for input: {1}")]
39 ParseFailed(#[source] combine::error::StringStreamError, String),
40 #[error("JNI call failed")]
41 JniCall(#[source] JniError),
42}
43
44#[derive(Debug, Error)]
45pub enum JniError {
46 #[error("Unknown error")]
47 Unknown,
48 #[error("Current thread is not attached to the Java VM")]
49 ThreadDetached,
50 #[error("JNI version error")]
51 WrongVersion,
52 #[error("Not enough memory")]
53 NoMemory,
54 #[error("VM already created")]
55 AlreadyCreated,
56 #[error("Invalid arguments")]
57 InvalidArguments,
58 #[error("Error code {0}")]
59 Other(sys::jint),
60}
61
62impl<T> From<::std::sync::TryLockError<T>> for Error {
63 fn from(_: ::std::sync::TryLockError<T>) -> Self {
64 Error::TryLock
65 }
66}
67
68pub fn jni_error_code_to_result(code: sys::jint) -> Result<()> {
69 match code {
70 sys::JNI_OK => Ok(()),
71 sys::JNI_ERR => Err(JniError::Unknown),
72 sys::JNI_EDETACHED => Err(JniError::ThreadDetached),
73 sys::JNI_EVERSION => Err(JniError::WrongVersion),
74 sys::JNI_ENOMEM => Err(JniError::NoMemory),
75 sys::JNI_EEXIST => Err(JniError::AlreadyCreated),
76 sys::JNI_EINVAL => Err(JniError::InvalidArguments),
77 _ => Err(JniError::Other(code)),
78 }
79 .map_err(Error::JniCall)
80}
81
82pub struct Exception {
83 pub class: String,
84 pub msg: String,
85}
86
87pub trait ToException {
88 fn to_exception(&self) -> Exception;
89}
90
91#[cfg(feature = "invocation")]
95#[derive(Debug, Error)]
96#[non_exhaustive]
97pub enum StartJvmError {
98 #[error("Couldn't automatically discover the Java VM's location (try setting the JAVA_HOME environment variable): {0}")]
106 NotFound(
107 #[from]
108 #[source]
109 java_locator::errors::JavaLocatorError,
110 ),
111
112 #[error("Couldn't load the Java VM shared library ({0}): {1}")]
117 LoadError(String, #[source] libloading::Error),
118
119 #[error("{0}")]
121 Create(
122 #[from]
123 #[source]
124 Error,
125 ),
126}
127
128#[cfg(feature = "invocation")]
129pub type StartJvmResult<T> = std::result::Result<T, StartJvmError>;