Skip to content

Commit

Permalink
Zerror (#231)
Browse files Browse the repository at this point in the history
* ZError: adding ZError exception, from which SessionException, JNIException and KeyExprException inherit.

* feat(ZError): correcting error types on JNI code

* ZError: specifying error  type on JNIConfig.

* ZError: fix tests

* ZError: removing JNIException.kt, SessionException.kt and KeyExprException.kt. Using ZError instead.

* ZError: cargo fmt

* Fix rebase error
  • Loading branch information
DariusIMP authored Sep 19, 2024
1 parent d443d9e commit 4b9f659
Show file tree
Hide file tree
Showing 31 changed files with 243 additions and 339 deletions.
32 changes: 16 additions & 16 deletions zenoh-jni/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use jni::{
};
use zenoh::Config;

use crate::{errors::Result, jni_error};
use crate::{session_error, throw_exception, utils::decode_string};
use crate::{errors::ZResult, zerror};
use crate::{throw_exception, utils::decode_string};

/// Loads the default configuration, returning a raw pointer to it.
///
Expand Down Expand Up @@ -52,9 +52,9 @@ pub extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_loadConfigFileViaJN
_class: JClass,
config_path: JString,
) -> *const Config {
|| -> Result<*const Config> {
|| -> ZResult<*const Config> {
let config_file_path = decode_string(&mut env, &config_path)?;
let config = Config::from_file(config_file_path).map_err(|err| session_error!(err))?;
let config = Config::from_file(config_file_path).map_err(|err| zerror!(err))?;
Ok(Arc::into_raw(Arc::new(config)))
}()
.unwrap_or_else(|err| {
Expand All @@ -76,13 +76,13 @@ pub extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_loadJsonConfigViaJN
_class: JClass,
json_config: JString,
) -> *const Config {
|| -> Result<*const Config> {
|| -> ZResult<*const Config> {
let json_config = decode_string(&mut env, &json_config)?;
let mut deserializer =
json5::Deserializer::from_str(&json_config).map_err(|err| session_error!(err))?;
json5::Deserializer::from_str(&json_config).map_err(|err| zerror!(err))?;
let config = Config::from_deserializer(&mut deserializer).map_err(|err| match err {
Ok(c) => session_error!("Invalid configuration: {}", c),
Err(e) => session_error!("JSON error: {}", e),
Ok(c) => zerror!("Invalid configuration: {}", c),
Err(e) => zerror!("JSON error: {}", e),
})?;
Ok(Arc::into_raw(Arc::new(config)))
}()
Expand All @@ -105,12 +105,12 @@ pub extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_loadYamlConfigViaJN
_class: JClass,
yaml_config: JString,
) -> *const Config {
|| -> Result<*const Config> {
|| -> ZResult<*const Config> {
let yaml_config = decode_string(&mut env, &yaml_config)?;
let deserializer = serde_yaml::Deserializer::from_str(&yaml_config);
let config = Config::from_deserializer(deserializer).map_err(|err| match err {
Ok(c) => session_error!("Invalid configuration: {}", c),
Err(e) => session_error!("YAML error: {}", e),
Ok(c) => zerror!("Invalid configuration: {}", c),
Err(e) => zerror!("YAML error: {}", e),
})?;
Ok(Arc::into_raw(Arc::new(config)))
}()
Expand All @@ -131,10 +131,10 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_getJsonViaJN
key: JString,
) -> jstring {
let arc_cfg: Arc<Config> = Arc::from_raw(cfg_ptr);
let result = || -> Result<jstring> {
let result = || -> ZResult<jstring> {
let key = decode_string(&mut env, &key)?;
let json = arc_cfg.get_json(&key).map_err(|err| session_error!(err))?;
let java_json = env.new_string(json).map_err(|err| jni_error!(err))?;
let json = arc_cfg.get_json(&key).map_err(|err| zerror!(err))?;
let java_json = env.new_string(json).map_err(|err| zerror!(err))?;
Ok(java_json.as_raw())
}()
.unwrap_or_else(|err| {
Expand All @@ -156,13 +156,13 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_insertJson5V
key: JString,
value: JString,
) {
|| -> Result<()> {
|| -> ZResult<()> {
let key = decode_string(&mut env, &key)?;
let value = decode_string(&mut env, &value)?;
let mut config = core::ptr::read(cfg_ptr);
let insert_result = config
.insert_json5(&key, &value)
.map_err(|err| session_error!(err));
.map_err(|err| zerror!(err));
core::ptr::write(cfg_ptr as *mut _, config);
insert_result
}()
Expand Down
63 changes: 13 additions & 50 deletions zenoh-jni/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,71 +26,34 @@ macro_rules! throw_exception {
}

#[macro_export]
macro_rules! jni_error {
macro_rules! zerror {
($arg:expr) => {
$crate::errors::Error::Jni($arg.to_string())
$crate::errors::ZError($arg.to_string())
};
($fmt:expr, $($arg:tt)*) => {
$crate::errors::Error::Jni(format!($fmt, $($arg)*))
$crate::errors::ZError(format!($fmt, $($arg)*))
};
}

#[macro_export]
macro_rules! session_error {
($arg:expr) => {
$crate::errors::Error::Session($arg.to_string())
};
($fmt:expr, $($arg:tt)*) => {
$crate::errors::Error::Session(format!($fmt, $($arg)*))
};

}

#[macro_export]
macro_rules! key_expr_error {
($arg:expr) => {
Error::KeyExpr($arg.to_string())
};
($fmt:expr, $($arg:tt)*) => {
Error::KeyExpr(format!($fmt, $($arg)*))
};
}

pub(crate) type Result<T> = core::result::Result<T, Error>;
pub(crate) type ZResult<T> = core::result::Result<T, ZError>;

#[derive(Debug)]
pub(crate) enum Error {
Session(String),
KeyExpr(String),
Jni(String),
}
pub(crate) struct ZError(pub String);

impl fmt::Display for Error {
impl fmt::Display for ZError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Session(msg) => write!(f, "{}", msg),
Error::KeyExpr(msg) => write!(f, "{}", msg),
Error::Jni(msg) => write!(f, "{}", msg),
}
write!(f, "{}", self.0)
}
}

impl Error {
fn get_associated_kotlin_exception(&self) -> String {
let class = match self {
Error::Session(_) => "io/zenoh/exceptions/SessionException",
Error::KeyExpr(_) => "io/zenoh/exceptions/KeyExprException",
Error::Jni(_) => "io/zenoh/exceptions/JNIException",
};
class.to_string()
}
impl ZError {
const KOTLIN_EXCEPTION_NAME: &'static str = "io/zenoh/exceptions/ZError";

pub fn throw_on_jvm(&self, env: &mut JNIEnv) -> Result<()> {
let exception_name = self.get_associated_kotlin_exception();
pub fn throw_on_jvm(&self, env: &mut JNIEnv) -> ZResult<()> {
let exception_class = env
.find_class(&exception_name)
.map_err(|err| jni_error!("Failed to retrieve exception class: {}", err))?;
.find_class(Self::KOTLIN_EXCEPTION_NAME)
.map_err(|err| zerror!("Failed to retrieve exception class: {}", err))?;
env.throw_new(exception_class, self.to_string())
.map_err(|err| jni_error!("Failed to throw exception: {}", err))
.map_err(|err| zerror!("Failed to throw exception: {}", err))
}
}
41 changes: 20 additions & 21 deletions zenoh-jni/src/key_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ use jni::sys::{jboolean, jint, jstring};
use jni::{objects::JString, JNIEnv};
use zenoh::key_expr::KeyExpr;

use crate::errors::Error;
use crate::errors::Result;
use crate::errors::ZResult;
use crate::utils::decode_string;
use crate::{jni_error, key_expr_error, session_error, throw_exception};
use crate::{throw_exception, zerror};

/// Validates the provided `key_expr` to be a valid key expression, returning it back
/// in case of success or throwing an exception in case of failure.
Expand Down Expand Up @@ -67,7 +66,7 @@ pub extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_autocanonizeViaJNI
.and_then(|key_expr| {
env.new_string(key_expr.to_string())
.map(|kexp| kexp.as_raw())
.map_err(|err| jni_error!(err))
.map_err(|err| zerror!(err))
})
.unwrap_or_else(|err| {
throw_exception!(env, err);
Expand Down Expand Up @@ -99,7 +98,7 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_intersectsV
key_expr_ptr_2: /*nullable*/ *const KeyExpr<'static>,
key_expr_str_2: JString,
) -> jboolean {
|| -> Result<jboolean> {
|| -> ZResult<jboolean> {
let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
let key_expr_2 = process_kotlin_key_expr(&mut env, &key_expr_str_2, key_expr_ptr_2)?;
Ok(key_expr_1.intersects(&key_expr_2) as jboolean)
Expand Down Expand Up @@ -134,7 +133,7 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_includesVia
key_expr_ptr_2: /*nullable*/ *const KeyExpr<'static>,
key_expr_str_2: JString,
) -> jboolean {
|| -> Result<jboolean> {
|| -> ZResult<jboolean> {
let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
let key_expr_2 = process_kotlin_key_expr(&mut env, &key_expr_str_2, key_expr_ptr_2)?;
Ok(key_expr_1.includes(&key_expr_2) as jboolean)
Expand Down Expand Up @@ -170,7 +169,7 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_relationToV
key_expr_ptr_2: /*nullable*/ *const KeyExpr<'static>,
key_expr_str_2: JString,
) -> jint {
|| -> Result<jint> {
|| -> ZResult<jint> {
let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
let key_expr_2 = process_kotlin_key_expr(&mut env, &key_expr_str_2, key_expr_ptr_2)?;
Ok(key_expr_1.relation_to(&key_expr_2) as jint)
Expand Down Expand Up @@ -204,15 +203,15 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_joinViaJNI(
key_expr_str_1: JString,
key_expr_2: JString,
) -> jstring {
|| -> Result<jstring> {
|| -> ZResult<jstring> {
let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
let key_expr_2_str = decode_string(&mut env, &key_expr_2)?;
let result = key_expr_1
.join(key_expr_2_str.as_str())
.map_err(|err| session_error!(err))?;
.map_err(|err| zerror!(err))?;
env.new_string(result.to_string())
.map(|kexp| kexp.as_raw())
.map_err(|err| jni_error!(err))
.map_err(|err| zerror!(err))
}()
.unwrap_or_else(|err| {
throw_exception!(env, err);
Expand Down Expand Up @@ -243,15 +242,15 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_concatViaJN
key_expr_str_1: JString,
key_expr_2: JString,
) -> jstring {
|| -> Result<jstring> {
|| -> ZResult<jstring> {
let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
let key_expr_2_str = decode_string(&mut env, &key_expr_2)?;
let result = key_expr_1
.concat(key_expr_2_str.as_str())
.map_err(|err| session_error!(err))?;
.map_err(|err| zerror!(err))?;
env.new_string(result.to_string())
.map(|kexp| kexp.as_raw())
.map_err(|err| jni_error!(err))
.map_err(|err| zerror!(err))
}()
.unwrap_or_else(|err| {
throw_exception!(env, err);
Expand Down Expand Up @@ -281,20 +280,20 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_freePtrViaJNI(
Arc::from_raw(key_expr_ptr);
}

fn validate_key_expr(env: &mut JNIEnv, key_expr: &JString) -> Result<KeyExpr<'static>> {
fn validate_key_expr(env: &mut JNIEnv, key_expr: &JString) -> ZResult<KeyExpr<'static>> {
let key_expr_str = decode_string(env, key_expr)
.map_err(|err| jni_error!("Unable to get key expression string value: '{}'.", err))?;
.map_err(|err| zerror!("Unable to get key expression string value: '{}'.", err))?;

KeyExpr::try_from(key_expr_str)
.map_err(|err| key_expr_error!("Unable to create key expression: '{}'.", err))
.map_err(|err| zerror!("Unable to create key expression: '{}'.", err))
}

fn autocanonize_key_expr(env: &mut JNIEnv, key_expr: &JString) -> Result<KeyExpr<'static>> {
fn autocanonize_key_expr(env: &mut JNIEnv, key_expr: &JString) -> ZResult<KeyExpr<'static>> {
decode_string(env, key_expr)
.map_err(|err| jni_error!("Unable to get key expression string value: '{}'.", err))
.map_err(|err| zerror!("Unable to get key expression string value: '{}'.", err))
.and_then(|key_expr_str| {
KeyExpr::autocanonize(key_expr_str)
.map_err(|err| key_expr_error!("Unable to create key expression: '{}'", err))
.map_err(|err| zerror!("Unable to create key expression: '{}'", err))
})
}

Expand All @@ -315,10 +314,10 @@ pub(crate) unsafe fn process_kotlin_key_expr(
env: &mut JNIEnv,
key_expr_str: &JString,
key_expr_ptr: *const KeyExpr<'static>,
) -> Result<KeyExpr<'static>> {
) -> ZResult<KeyExpr<'static>> {
if key_expr_ptr.is_null() {
let key_expr = decode_string(env, key_expr_str)
.map_err(|err| jni_error!("Unable to get key expression string value: '{}'.", err))?;
.map_err(|err| zerror!("Unable to get key expression string value: '{}'.", err))?;
Ok(KeyExpr::from_string_unchecked(key_expr))
} else {
let key_expr = Arc::from_raw(key_expr_ptr);
Expand Down
10 changes: 5 additions & 5 deletions zenoh-jni/src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use jni::{
JNIEnv,
};

use crate::{errors::Result, jni_error, throw_exception};
use crate::{errors::ZResult, throw_exception, zerror};

/// Redirects the Rust logs either to logcat for Android systems or to the standard output (for non-Android systems).
///
Expand All @@ -41,7 +41,7 @@ pub extern "C" fn Java_io_zenoh_Logger_00024Companion_startLogsViaJNI(
_class: JClass,
filter: JString,
) {
|| -> Result<()> {
|| -> ZResult<()> {
let log_level = parse_filter(&mut env, filter)?;
android_logd_logger::builder()
.parse_filters(log_level.as_str())
Expand All @@ -53,10 +53,10 @@ pub extern "C" fn Java_io_zenoh_Logger_00024Companion_startLogsViaJNI(
.unwrap_or_else(|err| throw_exception!(env, err))
}

fn parse_filter(env: &mut JNIEnv, log_level: JString) -> Result<String> {
let log_level = env.get_string(&log_level).map_err(|err| jni_error!(err))?;
fn parse_filter(env: &mut JNIEnv, log_level: JString) -> ZResult<String> {
let log_level = env.get_string(&log_level).map_err(|err| zerror!(err))?;
log_level
.to_str()
.map(|level| Ok(level.to_string()))
.map_err(|err| jni_error!(err))?
.map_err(|err| zerror!(err))?
}
13 changes: 7 additions & 6 deletions zenoh-jni/src/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ use jni::{
};
use zenoh::{pubsub::Publisher, Wait};

use crate::throw_exception;
use crate::{
errors::Result,
errors::ZResult,
utils::{decode_byte_array, decode_encoding},
zerror,
};
use crate::{session_error, throw_exception};

/// Performs a PUT operation on a Zenoh publisher via JNI.
///
Expand Down Expand Up @@ -56,7 +57,7 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIPublisher_putViaJNI(
publisher_ptr: *const Publisher<'static>,
) {
let publisher = Arc::from_raw(publisher_ptr);
let _ = || -> Result<()> {
let _ = || -> ZResult<()> {
let payload = decode_byte_array(&env, payload)?;
let mut publication = publisher.put(payload);
let encoding = decode_encoding(&mut env, encoding_id, &encoding_schema)?;
Expand All @@ -65,7 +66,7 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIPublisher_putViaJNI(
let attachment = decode_byte_array(&env, attachment)?;
publication = publication.attachment::<Vec<u8>>(attachment)
};
publication.wait().map_err(|err| session_error!(err))
publication.wait().map_err(|err| zerror!(err))
}()
.map_err(|err| throw_exception!(env, err));
std::mem::forget(publisher);
Expand Down Expand Up @@ -94,13 +95,13 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIPublisher_deleteViaJNI(
publisher_ptr: *const Publisher<'static>,
) {
let publisher = Arc::from_raw(publisher_ptr);
let _ = || -> Result<()> {
let _ = || -> ZResult<()> {
let mut delete = publisher.delete();
if !attachment.is_null() {
let attachment = decode_byte_array(&env, attachment)?;
delete = delete.attachment::<Vec<u8>>(attachment)
};
delete.wait().map_err(|err| session_error!(err))
delete.wait().map_err(|err| zerror!(err))
}()
.map_err(|err| throw_exception!(env, err));
std::mem::forget(publisher)
Expand Down
Loading

0 comments on commit 4b9f659

Please sign in to comment.