From 9fe988e29a1405cb8aa60628a1033149f89b06e6 Mon Sep 17 00:00:00 2001 From: Nikolay Petrov Date: Thu, 26 Oct 2023 17:01:51 +0300 Subject: [PATCH 1/5] improve errors returned from native --- Makefile | 6 +++- ngrok-java-native/src/lib.rs | 53 +++++++++++++++++------------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index ccb2d54..864d9ee 100644 --- a/Makefile +++ b/Makefile @@ -15,4 +15,8 @@ rebuild: .PHONY: install install: - mvn install --global-toolchains toolchains.xml \ No newline at end of file + mvn install --global-toolchains toolchains.xml + +.PHONY: reinstall +reinstall: + mvn clean install --global-toolchains toolchains.xml \ No newline at end of file diff --git a/ngrok-java-native/src/lib.rs b/ngrok-java-native/src/lib.rs index 4f0fc00..c1c8c96 100644 --- a/ngrok-java-native/src/lib.rs +++ b/ngrok-java-native/src/lib.rs @@ -378,7 +378,7 @@ impl<'local> NativeSessionRsImpl<'local> { &self, sess: MutexGuard, jttb: ComNgrokTcpBuilder<'local>, - ) -> TcpTunnelBuilder { + ) -> Result> { let mut bldr = sess.tcp_endpoint(); let jeb = jttb.as_com_ngrok_endpoint_builder(); @@ -411,14 +411,14 @@ impl<'local> NativeSessionRsImpl<'local> { bldr.remote_addr(remote_addr); } - bldr + Ok(bldr) } fn tls_builder( &self, sess: MutexGuard, jttb: ComNgrokTlsBuilder<'local>, - ) -> TlsTunnelBuilder { + ) -> Result> { let mut bldr = sess.tls_endpoint(); let jeb = jttb.as_com_ngrok_endpoint_builder(); @@ -470,17 +470,17 @@ impl<'local> NativeSessionRsImpl<'local> { ); } (cert, key) if cert.is_null() && key.is_null() => {} - _ => panic!("requires both terminationCertPEM and terminationKeyPEM"), + _ => return io_exc_err("requires both terminationCertPEM and terminationKeyPEM"), } - bldr + Ok(bldr) } fn http_builder( &self, sess: MutexGuard, jhtb: ComNgrokHttpBuilder<'local>, - ) -> HttpTunnelBuilder { + ) -> Result> { let mut bldr = sess.http_endpoint(); let jeb = jhtb.as_com_ngrok_endpoint_builder(); @@ -510,7 +510,7 @@ impl<'local> NativeSessionRsImpl<'local> { // from HttpTunnel.Builder if let Some(scheme) = jhtb.get_scheme_name(self.env).of_string(self.env) { - let scheme = Scheme::from_str(scheme.as_str()).expect("invalid scheme name"); + let scheme = Scheme::from_str(scheme.as_str()).map_err(io_exc)?; bldr.scheme(scheme); } @@ -623,14 +623,14 @@ impl<'local> NativeSessionRsImpl<'local> { bldr.webhook_verification(jwv.get_provider(self.env), jwv.get_secret(self.env)); } - bldr + Ok(bldr) } fn edge_builder( &self, sess: MutexGuard, jltb: ComNgrokEdgeBuilder<'local>, - ) -> LabeledTunnelBuilder { + ) -> Result> { let mut bldr = sess.labeled_tunnel(); let jmb = jltb.as_com_ngrok_metadata_builder(); @@ -657,7 +657,7 @@ impl<'local> NativeSessionRsImpl<'local> { }) .expect("cannot iterate over labels map"); - bldr + Ok(bldr) } fn labels_map( @@ -713,16 +713,14 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> .get_heartbeat_interval(self.env) .of_duration_ms(self.env) { - bldr.heartbeat_interval(interval) - .expect("invalid heartbeat interval"); + bldr.heartbeat_interval(interval).map_err(io_exc)?; } if let Some(tolerance) = jsb .get_heartbeat_tolerance(self.env) .of_duration_ms(self.env) { - bldr.heartbeat_tolerance(tolerance) - .expect("invalid heartbeat tolerance"); + bldr.heartbeat_tolerance(tolerance).map_err(io_exc)?; } let mut session_metadata = String::from(""); @@ -732,8 +730,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> } if let Some(server_addr) = jsb.get_server_addr(self.env).of_string(self.env) { - bldr.server_addr(server_addr) - .expect("invalid server address"); + bldr.server_addr(server_addr).map_err(io_exc)?; } let ca_cert = jsb.get_ca_cert(self.env); @@ -799,7 +796,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - let bldr = self.tcp_builder(sess, jttb); + let bldr = self.tcp_builder(sess, jttb)?; let tun = rt.block_on(bldr.listen()); match tun { @@ -828,9 +825,9 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - let bldr = self.tcp_builder(sess, jttb); + let bldr = self.tcp_builder(sess, jttb)?; - let url = Url::parse(jurl.as_string(self.env).as_str()).expect("cannot parse url"); + let url = Url::parse(jurl.as_string(self.env).as_str()).map_err(io_exc)?; let tun = rt.block_on(bldr.listen_and_forward(url)); match tun { @@ -858,7 +855,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - let bldr = self.tls_builder(sess, jttb); + let bldr = self.tls_builder(sess, jttb)?; let tun = rt.block_on(bldr.listen()); match tun { @@ -887,9 +884,9 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - let bldr = self.tls_builder(sess, jttb); + let bldr = self.tls_builder(sess, jttb)?; - let url = Url::parse(jurl.as_string(self.env).as_str()).expect("cannot parse url"); + let url = Url::parse(jurl.as_string(self.env).as_str()).map_err(io_exc)?; let tun = rt.block_on(bldr.listen_and_forward(url)); match tun { @@ -917,7 +914,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - let bldr = self.http_builder(sess, jttb); + let bldr = self.http_builder(sess, jttb)?; let tun = rt.block_on(bldr.listen()); match tun { @@ -946,9 +943,9 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - let bldr = self.http_builder(sess, jttb); + let bldr = self.http_builder(sess, jttb)?; - let url = Url::parse(jurl.as_string(self.env).as_str()).expect("cannot parse url"); + let url = Url::parse(jurl.as_string(self.env).as_str()).map_err(io_exc)?; let tun = rt.block_on(bldr.listen_and_forward(url)); match tun { @@ -976,7 +973,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - let bldr = self.edge_builder(sess, jttb); + let bldr = self.edge_builder(sess, jttb)?; let tun = rt.block_on(bldr.listen()); match tun { @@ -1005,9 +1002,9 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - let bldr = self.edge_builder(sess, jttb); + let bldr = self.edge_builder(sess, jttb)?; - let url = Url::parse(jurl.as_string(self.env).as_str()).expect("cannot parse url"); + let url = Url::parse(jurl.as_string(self.env).as_str()).map_err(io_exc)?; let tun = rt.block_on(bldr.listen_and_forward(url)); match tun { From 107f38eec1595134ea7c053b2d80fcd9120e985f Mon Sep 17 00:00:00 2001 From: Nikolay Petrov Date: Thu, 26 Oct 2023 19:02:36 +0300 Subject: [PATCH 2/5] extract info from more errors --- ngrok-java-native/src/lib.rs | 85 ++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/ngrok-java-native/src/lib.rs b/ngrok-java-native/src/lib.rs index c1c8c96..d22b59a 100644 --- a/ngrok-java-native/src/lib.rs +++ b/ngrok-java-native/src/lib.rs @@ -36,10 +36,10 @@ use ngrok::{ prelude::{EdgeConnInfo, EndpointConnInfo, ForwarderBuilder, TunnelBuilder}, session::{CommandHandler, HeartbeatHandler, Restart, Stop, Update}, tunnel::{ - EdgeInfo, EndpointInfo, HttpTunnel, LabeledTunnel, TcpTunnel, TlsTunnel, TunnelCloser, - TunnelInfo, + AcceptError, EdgeInfo, EndpointInfo, HttpTunnel, LabeledTunnel, TcpTunnel, TlsTunnel, + TunnelCloser, TunnelInfo, }, - EdgeConn, EndpointConn, Session, + EdgeConn, EndpointConn, Error as NError, Session, }; #[allow(clippy::all)] @@ -287,6 +287,28 @@ fn io_exc_err(e: E) -> Result> { Err(io_exc(e)) } +fn ngrok_exc(e: E) -> Error { + match e.error_code() { + Some(code) => io_exc(format!("{}\n\n{}", code, e.msg())), + None => io_exc(e.msg()), + } +} + +fn ngrok_exc_err(e: E) -> Result> { + Err(ngrok_exc(e)) +} + +fn accept_exc_err(e: AcceptError) -> Result> { + match e { + AcceptError::Reconnect(err) => match err.error_code() { + Some(code) => io_exc_err(format!("{}\n\n{}", code, err.msg())), + None => io_exc_err(err.msg()), + }, + AcceptError::Transport(err) => io_exc_err(err), + _ => io_exc_err(e), + } +} + struct CommandHandlerCallback { cbk: GlobalRef, } @@ -679,11 +701,11 @@ impl<'local> NativeSessionRsImpl<'local> { &self, this: ComNgrokNativeSession<'local>, tunnel_id: String, - ) -> Result<(), jaffi_support::Error> { + ) -> Result<(), Error> { let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - rt.block_on(sess.close_tunnel(tunnel_id)).map_err(io_exc) + rt.block_on(sess.close_tunnel(tunnel_id)).map_err(ngrok_exc) } } @@ -784,7 +806,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jsess, sess); Ok(jsess) } - Err(err) => io_exc_err(err), + Err(err) => ngrok_exc_err(err), } } @@ -812,7 +834,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jlistener, tun); Ok(jlistener) } - Err(err) => io_exc_err(err), + Err(err) => ngrok_exc_err(err), } } @@ -843,7 +865,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jforwarder, tun); Ok(jforwarder) } - Err(err) => io_exc_err(err), + Err(err) => ngrok_exc_err(err), } } @@ -871,7 +893,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jlistener, tun); Ok(jlistener) } - Err(err) => io_exc_err(err), + Err(err) => ngrok_exc_err(err), } } @@ -902,7 +924,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jforwarder, tun); Ok(jforwarder) } - Err(err) => io_exc_err(err), + Err(err) => ngrok_exc_err(err), } } @@ -930,7 +952,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jlistener, tun); Ok(jlistener) } - Err(err) => io_exc_err(err), + Err(err) => ngrok_exc_err(err), } } @@ -961,7 +983,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jforwarder, tun); Ok(jforwarder) } - Err(err) => io_exc_err(err), + Err(err) => ngrok_exc_err(err), } } @@ -989,7 +1011,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jlistener, tun); Ok(jlistener) } - Err(err) => io_exc_err(err), + Err(err) => ngrok_exc_err(err), } } @@ -1020,7 +1042,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jforwarder, tun); Ok(jforwarder) } - Err(err) => io_exc_err(err), + Err(err) => ngrok_exc_err(err), } } @@ -1028,7 +1050,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> &self, this: ComNgrokNativeSession<'local>, id: String, - ) -> Result<(), jaffi_support::Error> { + ) -> Result<(), Error> { self.close_tunnel(this, id) } @@ -1036,18 +1058,15 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> &self, this: ComNgrokNativeSession<'local>, id: String, - ) -> Result<(), jaffi_support::Error> { + ) -> Result<(), Error> { self.close_tunnel(this, id) } - fn close( - &self, - this: ComNgrokNativeSession<'local>, - ) -> Result<(), jaffi_support::Error> { + fn close(&self, this: ComNgrokNativeSession<'local>) -> Result<(), Error> { let rt = RT.get().expect("runtime not initialized"); let mut sess: Session = self.take_native(this); - rt.block_on(sess.close()).map_err(io_exc) + rt.block_on(sess.close()).map_err(ngrok_exc) } } @@ -1085,7 +1104,7 @@ impl<'local> com_ngrok::NativeTcpListenerRs<'local> for NativeTcpListenerRsImpl< Ok(jconn) } Ok(None) => io_exc_err("could not get next conn"), - Err(err) => io_exc_err(err), + Err(err) => accept_exc_err(err), } } @@ -1093,7 +1112,7 @@ impl<'local> com_ngrok::NativeTcpListenerRs<'local> for NativeTcpListenerRsImpl< let rt = RT.get().expect("runtime not initialized"); let mut tun: TcpTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(io_exc) + rt.block_on(tun.close()).map_err(ngrok_exc) } } @@ -1127,7 +1146,7 @@ impl<'local> com_ngrok::NativeTcpForwarderRs<'local> for NativeTcpForwarderRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: Forwarder = self.take_native(this); - rt.block_on(tun.close()).map_err(io_exc) + rt.block_on(tun.close()).map_err(ngrok_exc) } } @@ -1165,7 +1184,7 @@ impl<'local> com_ngrok::NativeTlsListenerRs<'local> for NativeTlsListenerRsImpl< Ok(jconn) } Ok(None) => io_exc_err("could not get next conn"), - Err(err) => io_exc_err(err), + Err(err) => accept_exc_err(err), } } @@ -1173,7 +1192,7 @@ impl<'local> com_ngrok::NativeTlsListenerRs<'local> for NativeTlsListenerRsImpl< let rt = RT.get().expect("runtime not initialized"); let mut tun: TlsTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(io_exc) + rt.block_on(tun.close()).map_err(ngrok_exc) } } @@ -1207,7 +1226,7 @@ impl<'local> com_ngrok::NativeTlsForwarderRs<'local> for NativeTlsForwarderRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: TlsTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(io_exc) + rt.block_on(tun.close()).map_err(ngrok_exc) } } @@ -1245,7 +1264,7 @@ impl<'local> com_ngrok::NativeHttpListenerRs<'local> for NativeHttpListenerRsImp Ok(jconn) } Ok(None) => io_exc_err("could not get next conn"), - Err(err) => io_exc_err(err), + Err(err) => accept_exc_err(err), } } @@ -1256,7 +1275,7 @@ impl<'local> com_ngrok::NativeHttpListenerRs<'local> for NativeHttpListenerRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: HttpTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(io_exc) + rt.block_on(tun.close()).map_err(ngrok_exc) } } @@ -1293,7 +1312,7 @@ impl<'local> com_ngrok::NativeHttpForwarderRs<'local> for NativeHttpForwarderRsI let rt = RT.get().expect("runtime not initialized"); let mut tun: HttpTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(io_exc) + rt.block_on(tun.close()).map_err(ngrok_exc) } } @@ -1337,7 +1356,7 @@ impl<'local> com_ngrok::NativeEdgeListenerRs<'local> for NativeEdgeListenerRsImp Ok(jconn) } Ok(None) => io_exc_err("could not get next conn"), - Err(err) => io_exc_err(err), + Err(err) => accept_exc_err(err), } } @@ -1348,7 +1367,7 @@ impl<'local> com_ngrok::NativeEdgeListenerRs<'local> for NativeEdgeListenerRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: LabeledTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(io_exc) + rt.block_on(tun.close()).map_err(ngrok_exc) } } @@ -1385,7 +1404,7 @@ impl<'local> com_ngrok::NativeEdgeForwarderRs<'local> for NativeEdgeForwarderRsI let rt = RT.get().expect("runtime not initialized"); let mut tun: LabeledTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(io_exc) + rt.block_on(tun.close()).map_err(ngrok_exc) } } From 96a6cd2945ef5e8bf433130a85589e462f66622d Mon Sep 17 00:00:00 2001 From: Nikolay Petrov Date: Fri, 27 Oct 2023 14:48:33 +0300 Subject: [PATCH 3/5] add NgrokException and throw when appropriate --- ngrok-java-native/build.rs | 1 + ngrok-java-native/src/lib.rs | 68 +++++++++++++------ .../main/java/com/ngrok/NgrokException.java | 22 ++++++ 3 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 ngrok-java/src/main/java/com/ngrok/NgrokException.java diff --git a/ngrok-java-native/build.rs b/ngrok-java-native/build.rs index ab24847..acdb370 100644 --- a/ngrok-java-native/build.rs +++ b/ngrok-java-native/build.rs @@ -47,6 +47,7 @@ fn main() -> Result<(), Box> { Cow::from("com.ngrok.TlsBuilder"), Cow::from("com.ngrok.AbstractEdge"), Cow::from("com.ngrok.AbstractEndpoint"), + Cow::from("com.ngrok.NgrokException"), ]; let output_dir = PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR not set")); diff --git a/ngrok-java-native/src/lib.rs b/ngrok-java-native/src/lib.rs index d22b59a..e9164b8 100644 --- a/ngrok-java-native/src/lib.rs +++ b/ngrok-java-native/src/lib.rs @@ -5,10 +5,11 @@ use com_ngrok::{ ComNgrokNativeEdgeForwarder, ComNgrokNativeEdgeListener, ComNgrokNativeEndpointConnection, ComNgrokNativeHttpForwarder, ComNgrokNativeHttpListener, ComNgrokNativeSession, ComNgrokNativeSessionClass, ComNgrokNativeTcpForwarder, ComNgrokNativeTcpListener, - ComNgrokNativeTlsForwarder, ComNgrokNativeTlsListener, ComNgrokRuntimeLogger, - ComNgrokSessionBuilder, ComNgrokSessionClientInfo, ComNgrokSessionCommandHandler, - ComNgrokSessionHeartbeatHandler, ComNgrokTcpBuilder, ComNgrokTlsBuilder, IOException, - IOExceptionErr, JavaNetUrl, JavaUtilList, JavaUtilMap, JavaUtilOptional, + ComNgrokNativeTlsForwarder, ComNgrokNativeTlsListener, ComNgrokNgrokException, + ComNgrokRuntimeLogger, ComNgrokSessionBuilder, ComNgrokSessionClientInfo, + ComNgrokSessionCommandHandler, ComNgrokSessionHeartbeatHandler, ComNgrokTcpBuilder, + ComNgrokTlsBuilder, IOException, IOExceptionErr, JavaNetUrl, JavaUtilList, JavaUtilMap, + JavaUtilOptional, }; use futures::TryStreamExt; use once_cell::sync::OnceCell; @@ -20,10 +21,10 @@ use url::Url; use jaffi_support::{ jni::{ - objects::{GlobalRef, JByteBuffer, JObject, JString, JValue}, + objects::{GlobalRef, JByteBuffer, JObject, JString, JThrowable, JValue}, JNIEnv, JavaVM, }, - Error, + Error, NullObject, }; use ngrok::{ @@ -189,6 +190,27 @@ trait JNIExt<'local> { ) } } + + fn ngrok_exc_err< + T: std::convert::From>, + E: NError, + >( + &self, + err: E, + ) -> Result> { + if let Some(code) = err.error_code() { + let nexc = ComNgrokNgrokException::new_1com_ngrok_ngrok_exception( + *self.get_env(), + code.into(), + err.msg(), + ); + if self.get_env().throw(nexc).is_ok() { + return Ok(NullObject::null()); + } + return io_exc_err(format!("{}\n\n{}", code, err.msg())); + } + io_exc_err(err) + } } impl<'local> JavaUtilList<'local> { @@ -294,10 +316,6 @@ fn ngrok_exc(e: E) -> Error { } } -fn ngrok_exc_err(e: E) -> Result> { - Err(ngrok_exc(e)) -} - fn accept_exc_err(e: AcceptError) -> Result> { match e { AcceptError::Reconnect(err) => match err.error_code() { @@ -309,6 +327,15 @@ fn accept_exc_err(e: AcceptError) -> Result> { } } +impl<'local> jaffi_support::jni::descriptors::Desc<'local, JThrowable<'local>> + for ComNgrokNgrokException<'local> +{ + fn lookup(self, _: &JNIEnv<'local>) -> jaffi_support::jni::errors::Result> { + let thr: JObject = self.into(); + Ok(thr.into()) + } +} + struct CommandHandlerCallback { cbk: GlobalRef, } @@ -806,7 +833,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jsess, sess); Ok(jsess) } - Err(err) => ngrok_exc_err(err), + Err(err) => self.ngrok_exc_err(err), } } @@ -820,8 +847,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let sess: MutexGuard = self.get_native(this); let bldr = self.tcp_builder(sess, jttb)?; - let tun = rt.block_on(bldr.listen()); - match tun { + match rt.block_on(bldr.listen()) { Ok(tun) => { let jlistener = ComNgrokNativeTcpListener::new_1com_ngrok_native_tcp_listener( self.env, @@ -834,7 +860,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jlistener, tun); Ok(jlistener) } - Err(err) => ngrok_exc_err(err), + Err(err) => self.ngrok_exc_err(err), } } @@ -865,7 +891,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jforwarder, tun); Ok(jforwarder) } - Err(err) => ngrok_exc_err(err), + Err(err) => self.ngrok_exc_err(err), } } @@ -893,7 +919,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jlistener, tun); Ok(jlistener) } - Err(err) => ngrok_exc_err(err), + Err(err) => self.ngrok_exc_err(err), } } @@ -924,7 +950,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jforwarder, tun); Ok(jforwarder) } - Err(err) => ngrok_exc_err(err), + Err(err) => self.ngrok_exc_err(err), } } @@ -952,7 +978,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jlistener, tun); Ok(jlistener) } - Err(err) => ngrok_exc_err(err), + Err(err) => self.ngrok_exc_err(err), } } @@ -983,7 +1009,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jforwarder, tun); Ok(jforwarder) } - Err(err) => ngrok_exc_err(err), + Err(err) => self.ngrok_exc_err(err), } } @@ -1011,7 +1037,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jlistener, tun); Ok(jlistener) } - Err(err) => ngrok_exc_err(err), + Err(err) => self.ngrok_exc_err(err), } } @@ -1042,7 +1068,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> self.set_native(jforwarder, tun); Ok(jforwarder) } - Err(err) => ngrok_exc_err(err), + Err(err) => self.ngrok_exc_err(err), } } diff --git a/ngrok-java/src/main/java/com/ngrok/NgrokException.java b/ngrok-java/src/main/java/com/ngrok/NgrokException.java new file mode 100644 index 0000000..f78c410 --- /dev/null +++ b/ngrok-java/src/main/java/com/ngrok/NgrokException.java @@ -0,0 +1,22 @@ +package com.ngrok; + +import java.io.IOException; + +public class NgrokException extends IOException { + private final String code; + private final String details; + + public NgrokException(String code, String details) { + super(String.format("%s\n\n%s", code, details)); + this.code = code; + this.details = details; + } + + public String getCode() { + return code; + } + + public String getDetails() { + return details; + } +} From bc9966993a4cd9995923a0e6b2cbfa16516b6e14 Mon Sep 17 00:00:00 2001 From: Nikolay Petrov Date: Fri, 27 Oct 2023 15:34:19 +0300 Subject: [PATCH 4/5] more all specific ngrok errors to generic trait --- ngrok-java-native/src/lib.rs | 105 +++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 47 deletions(-) diff --git a/ngrok-java-native/src/lib.rs b/ngrok-java-native/src/lib.rs index e9164b8..a5a9f6d 100644 --- a/ngrok-java-native/src/lib.rs +++ b/ngrok-java-native/src/lib.rs @@ -198,6 +198,18 @@ trait JNIExt<'local> { &self, err: E, ) -> Result> { + match self.ngrok_exc_err_void(err) { + Ok(_) => Ok(NullObject::null()), + Err(err) => Err(err), + } + } + + fn ngrok_exc_err_void< + E: NError, + >( + &self, + err: E, + ) -> Result<(), Error> { if let Some(code) = err.error_code() { let nexc = ComNgrokNgrokException::new_1com_ngrok_ngrok_exception( *self.get_env(), @@ -205,12 +217,36 @@ trait JNIExt<'local> { err.msg(), ); if self.get_env().throw(nexc).is_ok() { - return Ok(NullObject::null()); + return Ok(()); } return io_exc_err(format!("{}\n\n{}", code, err.msg())); } io_exc_err(err) } + + fn accept_exc_err< + T: std::convert::From>, + >(&self, err: AcceptError) -> Result> { + match err { + // TODO next rust update + AcceptError::Reconnect(err) => match err.error_code() { + Some(code) => { + let nexc = ComNgrokNgrokException::new_1com_ngrok_ngrok_exception( + *self.get_env(), + code.into(), + err.msg(), + ); + if self.get_env().throw(nexc).is_ok() { + return Ok(NullObject::null()); + } + io_exc_err(format!("{}\n\n{}", code, err.msg())) + }, + None => io_exc_err(err), + }, + AcceptError::Transport(err) => io_exc_err(err), + _ => io_exc_err(err), + } + } } impl<'local> JavaUtilList<'local> { @@ -309,24 +345,6 @@ fn io_exc_err(e: E) -> Result> { Err(io_exc(e)) } -fn ngrok_exc(e: E) -> Error { - match e.error_code() { - Some(code) => io_exc(format!("{}\n\n{}", code, e.msg())), - None => io_exc(e.msg()), - } -} - -fn accept_exc_err(e: AcceptError) -> Result> { - match e { - AcceptError::Reconnect(err) => match err.error_code() { - Some(code) => io_exc_err(format!("{}\n\n{}", code, err.msg())), - None => io_exc_err(err.msg()), - }, - AcceptError::Transport(err) => io_exc_err(err), - _ => io_exc_err(e), - } -} - impl<'local> jaffi_support::jni::descriptors::Desc<'local, JThrowable<'local>> for ComNgrokNgrokException<'local> { @@ -732,7 +750,7 @@ impl<'local> NativeSessionRsImpl<'local> { let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - rt.block_on(sess.close_tunnel(tunnel_id)).map_err(ngrok_exc) + rt.block_on(sess.close_tunnel(tunnel_id)).or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -877,8 +895,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let url = Url::parse(jurl.as_string(self.env).as_str()).map_err(io_exc)?; - let tun = rt.block_on(bldr.listen_and_forward(url)); - match tun { + match rt.block_on(bldr.listen_and_forward(url)) { Ok(tun) => { let jforwarder = ComNgrokNativeTcpForwarder::new_1com_ngrok_native_tcp_forwarder( self.env, @@ -905,8 +922,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let sess: MutexGuard = self.get_native(this); let bldr = self.tls_builder(sess, jttb)?; - let tun = rt.block_on(bldr.listen()); - match tun { + match rt.block_on(bldr.listen()) { Ok(tun) => { let jlistener = ComNgrokNativeTlsListener::new_1com_ngrok_native_tls_listener( self.env, @@ -936,8 +952,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let url = Url::parse(jurl.as_string(self.env).as_str()).map_err(io_exc)?; - let tun = rt.block_on(bldr.listen_and_forward(url)); - match tun { + match rt.block_on(bldr.listen_and_forward(url)) { Ok(tun) => { let jforwarder = ComNgrokNativeTlsForwarder::new_1com_ngrok_native_tls_forwarder( self.env, @@ -964,8 +979,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let sess: MutexGuard = self.get_native(this); let bldr = self.http_builder(sess, jttb)?; - let tun = rt.block_on(bldr.listen()); - match tun { + match rt.block_on(bldr.listen()) { Ok(tun) => { let jlistener = ComNgrokNativeHttpListener::new_1com_ngrok_native_http_listener( self.env, @@ -995,8 +1009,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let url = Url::parse(jurl.as_string(self.env).as_str()).map_err(io_exc)?; - let tun = rt.block_on(bldr.listen_and_forward(url)); - match tun { + match rt.block_on(bldr.listen_and_forward(url)) { Ok(tun) => { let jforwarder = ComNgrokNativeHttpForwarder::new_1com_ngrok_native_http_forwarder( self.env, @@ -1023,8 +1036,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let sess: MutexGuard = self.get_native(this); let bldr = self.edge_builder(sess, jttb)?; - let tun = rt.block_on(bldr.listen()); - match tun { + match rt.block_on(bldr.listen()) { Ok(tun) => { let jlistener = ComNgrokNativeEdgeListener::new_1com_ngrok_native_edge_listener( self.env, @@ -1054,8 +1066,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let url = Url::parse(jurl.as_string(self.env).as_str()).map_err(io_exc)?; - let tun = rt.block_on(bldr.listen_and_forward(url)); - match tun { + match rt.block_on(bldr.listen_and_forward(url)) { Ok(tun) => { let jforwarder = ComNgrokNativeEdgeForwarder::new_1com_ngrok_native_edge_forwarder( self.env, @@ -1092,7 +1103,7 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let mut sess: Session = self.take_native(this); - rt.block_on(sess.close()).map_err(ngrok_exc) + rt.block_on(sess.close()).or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1130,7 +1141,7 @@ impl<'local> com_ngrok::NativeTcpListenerRs<'local> for NativeTcpListenerRsImpl< Ok(jconn) } Ok(None) => io_exc_err("could not get next conn"), - Err(err) => accept_exc_err(err), + Err(err) => self.accept_exc_err(err), } } @@ -1138,7 +1149,7 @@ impl<'local> com_ngrok::NativeTcpListenerRs<'local> for NativeTcpListenerRsImpl< let rt = RT.get().expect("runtime not initialized"); let mut tun: TcpTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(ngrok_exc) + rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1172,7 +1183,7 @@ impl<'local> com_ngrok::NativeTcpForwarderRs<'local> for NativeTcpForwarderRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: Forwarder = self.take_native(this); - rt.block_on(tun.close()).map_err(ngrok_exc) + rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1210,7 +1221,7 @@ impl<'local> com_ngrok::NativeTlsListenerRs<'local> for NativeTlsListenerRsImpl< Ok(jconn) } Ok(None) => io_exc_err("could not get next conn"), - Err(err) => accept_exc_err(err), + Err(err) => self.accept_exc_err(err), } } @@ -1218,7 +1229,7 @@ impl<'local> com_ngrok::NativeTlsListenerRs<'local> for NativeTlsListenerRsImpl< let rt = RT.get().expect("runtime not initialized"); let mut tun: TlsTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(ngrok_exc) + rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1252,7 +1263,7 @@ impl<'local> com_ngrok::NativeTlsForwarderRs<'local> for NativeTlsForwarderRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: TlsTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(ngrok_exc) + rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1290,7 +1301,7 @@ impl<'local> com_ngrok::NativeHttpListenerRs<'local> for NativeHttpListenerRsImp Ok(jconn) } Ok(None) => io_exc_err("could not get next conn"), - Err(err) => accept_exc_err(err), + Err(err) => self.accept_exc_err(err), } } @@ -1301,7 +1312,7 @@ impl<'local> com_ngrok::NativeHttpListenerRs<'local> for NativeHttpListenerRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: HttpTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(ngrok_exc) + rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1338,7 +1349,7 @@ impl<'local> com_ngrok::NativeHttpForwarderRs<'local> for NativeHttpForwarderRsI let rt = RT.get().expect("runtime not initialized"); let mut tun: HttpTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(ngrok_exc) + rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1382,7 +1393,7 @@ impl<'local> com_ngrok::NativeEdgeListenerRs<'local> for NativeEdgeListenerRsImp Ok(jconn) } Ok(None) => io_exc_err("could not get next conn"), - Err(err) => accept_exc_err(err), + Err(err) => self.accept_exc_err(err), } } @@ -1393,7 +1404,7 @@ impl<'local> com_ngrok::NativeEdgeListenerRs<'local> for NativeEdgeListenerRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: LabeledTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(ngrok_exc) + rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1430,7 +1441,7 @@ impl<'local> com_ngrok::NativeEdgeForwarderRs<'local> for NativeEdgeForwarderRsI let rt = RT.get().expect("runtime not initialized"); let mut tun: LabeledTunnel = self.take_native(this); - rt.block_on(tun.close()).map_err(ngrok_exc) + rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) } } From f297813a01c4870efdbd3d27967e740c154f4d9b Mon Sep 17 00:00:00 2001 From: Nikolay Petrov Date: Fri, 27 Oct 2023 15:48:47 +0300 Subject: [PATCH 5/5] use match and format --- ngrok-java-native/src/lib.rs | 88 +++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/ngrok-java-native/src/lib.rs b/ngrok-java-native/src/lib.rs index a5a9f6d..966a6b4 100644 --- a/ngrok-java-native/src/lib.rs +++ b/ngrok-java-native/src/lib.rs @@ -204,42 +204,25 @@ trait JNIExt<'local> { } } - fn ngrok_exc_err_void< - E: NError, - >( - &self, - err: E, - ) -> Result<(), Error> { - if let Some(code) = err.error_code() { - let nexc = ComNgrokNgrokException::new_1com_ngrok_ngrok_exception( - *self.get_env(), - code.into(), - err.msg(), - ); - if self.get_env().throw(nexc).is_ok() { - return Ok(()); - } - return io_exc_err(format!("{}\n\n{}", code, err.msg())); + fn ngrok_exc_err_void(&self, err: E) -> Result<(), Error> { + match err.error_code() { + Some(code) => self + .throw_ngrok_exception(code.into(), err.msg()) + .map_err(|_| io_exc(format!("{}\n\n{}", code, err.msg()))), + None => io_exc_err(err), } - io_exc_err(err) } - fn accept_exc_err< - T: std::convert::From>, - >(&self, err: AcceptError) -> Result> { + fn accept_exc_err>>( + &self, + err: AcceptError, + ) -> Result> { match err { - // TODO next rust update + // TODO next rust update use ngrok_exc_err AcceptError::Reconnect(err) => match err.error_code() { - Some(code) => { - let nexc = ComNgrokNgrokException::new_1com_ngrok_ngrok_exception( - *self.get_env(), - code.into(), - err.msg(), - ); - if self.get_env().throw(nexc).is_ok() { - return Ok(NullObject::null()); - } - io_exc_err(format!("{}\n\n{}", code, err.msg())) + Some(code) => match self.throw_ngrok_exception(code.into(), err.msg()) { + Ok(_) => Ok(NullObject::null()), + Err(_) => io_exc_err(format!("{}\n\n{}", code, err.msg())), }, None => io_exc_err(err), }, @@ -247,6 +230,19 @@ trait JNIExt<'local> { _ => io_exc_err(err), } } + + fn throw_ngrok_exception( + &self, + code: String, + details: String, + ) -> Result<(), jaffi_support::jni::errors::Error> { + self.get_env() + .throw(ComNgrokNgrokException::new_1com_ngrok_ngrok_exception( + *self.get_env(), + code, + details, + )) + } } impl<'local> JavaUtilList<'local> { @@ -750,7 +746,8 @@ impl<'local> NativeSessionRsImpl<'local> { let rt = RT.get().expect("runtime not initialized"); let sess: MutexGuard = self.get_native(this); - rt.block_on(sess.close_tunnel(tunnel_id)).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(sess.close_tunnel(tunnel_id)) + .or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1103,7 +1100,8 @@ impl<'local> com_ngrok::NativeSessionRs<'local> for NativeSessionRsImpl<'local> let rt = RT.get().expect("runtime not initialized"); let mut sess: Session = self.take_native(this); - rt.block_on(sess.close()).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(sess.close()) + .or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1149,7 +1147,8 @@ impl<'local> com_ngrok::NativeTcpListenerRs<'local> for NativeTcpListenerRsImpl< let rt = RT.get().expect("runtime not initialized"); let mut tun: TcpTunnel = self.take_native(this); - rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(tun.close()) + .or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1183,7 +1182,8 @@ impl<'local> com_ngrok::NativeTcpForwarderRs<'local> for NativeTcpForwarderRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: Forwarder = self.take_native(this); - rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(tun.close()) + .or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1229,7 +1229,8 @@ impl<'local> com_ngrok::NativeTlsListenerRs<'local> for NativeTlsListenerRsImpl< let rt = RT.get().expect("runtime not initialized"); let mut tun: TlsTunnel = self.take_native(this); - rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(tun.close()) + .or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1263,7 +1264,8 @@ impl<'local> com_ngrok::NativeTlsForwarderRs<'local> for NativeTlsForwarderRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: TlsTunnel = self.take_native(this); - rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(tun.close()) + .or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1312,7 +1314,8 @@ impl<'local> com_ngrok::NativeHttpListenerRs<'local> for NativeHttpListenerRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: HttpTunnel = self.take_native(this); - rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(tun.close()) + .or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1349,7 +1352,8 @@ impl<'local> com_ngrok::NativeHttpForwarderRs<'local> for NativeHttpForwarderRsI let rt = RT.get().expect("runtime not initialized"); let mut tun: HttpTunnel = self.take_native(this); - rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(tun.close()) + .or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1404,7 +1408,8 @@ impl<'local> com_ngrok::NativeEdgeListenerRs<'local> for NativeEdgeListenerRsImp let rt = RT.get().expect("runtime not initialized"); let mut tun: LabeledTunnel = self.take_native(this); - rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(tun.close()) + .or_else(|err| self.ngrok_exc_err_void(err)) } } @@ -1441,7 +1446,8 @@ impl<'local> com_ngrok::NativeEdgeForwarderRs<'local> for NativeEdgeForwarderRsI let rt = RT.get().expect("runtime not initialized"); let mut tun: LabeledTunnel = self.take_native(this); - rt.block_on(tun.close()).or_else(|err| self.ngrok_exc_err_void(err)) + rt.block_on(tun.close()) + .or_else(|err| self.ngrok_exc_err_void(err)) } }