From fe1ddf32b3e66524d4c788efc5d34c5a5e04ef3d Mon Sep 17 00:00:00 2001 From: Sam Cao Date: Thu, 1 Aug 2024 08:50:12 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A6=84=20refactor:=20Revise=20error=20han?= =?UTF-8?q?dling=204?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rust/src/error.rs | 109 +++++++++++++----- .../swc4j/exceptions/Swc4jCoreException.java | 50 ++++++-- .../javet/swc4j/plugins/Swc4jPluginHost.java | 13 +-- .../jsfuck/Swc4jPluginHostJsFuckDecoder.java | 19 ++- .../swc4j/plugins/TestSwc4jPluginHost.java | 49 +++++++- 5 files changed, 179 insertions(+), 61 deletions(-) diff --git a/rust/src/error.rs b/rust/src/error.rs index 440468ff..d8770796 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -16,7 +16,7 @@ */ use jni::objects::{GlobalRef, JStaticMethodID, JThrowable}; -use jni::sys::jobject; +use jni::sys::{jobject, jvalue}; use jni::JNIEnv; use std::ptr::null_mut; @@ -43,21 +43,21 @@ impl JavaCoreException { .get_static_method_id( &class, "parseError", - "(Ljava/lang/String;)Lcom/caoccao/javet/swc4j/exceptions/Swc4jCoreException;", + "(Ljava/lang/String;Ljava/lang/Throwable;)Lcom/caoccao/javet/swc4j/exceptions/Swc4jCoreException;", ) .expect("Couldn't find static method Swc4jCoreException.parseError"); let method_transform_error = env .get_static_method_id( &class, "transformError", - "(Ljava/lang/String;)Lcom/caoccao/javet/swc4j/exceptions/Swc4jCoreException;", + "(Ljava/lang/String;Ljava/lang/Throwable;)Lcom/caoccao/javet/swc4j/exceptions/Swc4jCoreException;", ) .expect("Couldn't find static method Swc4jCoreException.transformError"); let method_transpile_error = env .get_static_method_id( &class, "transpileError", - "(Ljava/lang/String;)Lcom/caoccao/javet/swc4j/exceptions/Swc4jCoreException;", + "(Ljava/lang/String;Ljava/lang/Throwable;)Lcom/caoccao/javet/swc4j/exceptions/Swc4jCoreException;", ) .expect("Couldn't find static method Swc4jCoreException.transpileError"); JavaCoreException { @@ -68,43 +68,79 @@ impl JavaCoreException { } } - pub fn throw_parse_error<'local, 'a>(&self, env: &mut JNIEnv<'local>, message: &'a str) { + pub fn throw_parse_error<'local, 'a>( + &self, + env: &mut JNIEnv<'local>, + message: &'a str, + cause: Option>, + ) { let java_message = string_to_jstring!(env, message); let message = object_to_jvalue!(java_message); - let exception = call_static_as_object!(env, &self.class, &self.method_parse_error, &[message], "parseError()") - .expect("Couldn't call static method Swc4jCoreException.parseError()"); + let cause = if let Some(cause) = cause { + object_to_jvalue!(cause) + } else { + jvalue { l: null_mut() } + }; + let exception = call_static_as_object!( + env, + &self.class, + &self.method_parse_error, + &[message, cause], + "parseError()" + ) + .expect("Couldn't call static method Swc4jCoreException.parseError()"); let exception = unsafe { JThrowable::from_raw(exception.as_raw()) }; - let _ = env.throw(exception); + env.throw(exception).expect("Couldn't call throw parse error"); } - pub fn throw_transform_error<'local, 'a>(&self, env: &mut JNIEnv<'local>, message: &'a str) { + pub fn throw_transform_error<'local, 'a>( + &self, + env: &mut JNIEnv<'local>, + message: &'a str, + cause: Option>, + ) { let java_message = string_to_jstring!(env, message); let message = object_to_jvalue!(java_message); + let cause = if let Some(cause) = cause { + object_to_jvalue!(cause) + } else { + jvalue { l: null_mut() } + }; let exception = call_static_as_object!( env, &self.class, &self.method_transform_error, - &[message], + &[message, cause], "transformError()" ) .expect("Couldn't call static method Swc4jCoreException.transformError()"); let exception = unsafe { JThrowable::from_raw(exception.as_raw()) }; - let _ = env.throw(exception); + env.throw(exception).expect("Couldn't call throw transform error"); } - pub fn throw_transpile_error<'local, 'a>(&self, env: &mut JNIEnv<'local>, message: &'a str) { + pub fn throw_transpile_error<'local, 'a>( + &self, + env: &mut JNIEnv<'local>, + message: &'a str, + cause: Option>, + ) { let java_message = string_to_jstring!(env, message); let message = object_to_jvalue!(java_message); + let cause = if let Some(cause) = cause { + object_to_jvalue!(cause) + } else { + jvalue { l: null_mut() } + }; let exception = call_static_as_object!( env, &self.class, &self.method_transpile_error, - &[message], + &[message, cause], "transpileError()" ) .expect("Couldn't call static method Swc4jCoreException.transpileError()"); let exception = unsafe { JThrowable::from_raw(exception.as_raw()) }; - let _ = env.throw(exception); + env.throw(exception).expect("Couldn't call throw transpile error"); } } @@ -117,28 +153,43 @@ pub fn init<'local>(env: &mut JNIEnv<'local>) { } pub fn throw_parse_error<'local, 'a>(env: &mut JNIEnv<'local>, message: &'a str) -> jobject { - unsafe { - JAVA_CORE_EXCEPTION.as_ref().unwrap().throw_parse_error(env, message); - } + let java_core_exception = unsafe { JAVA_CORE_EXCEPTION.as_ref().unwrap() }; + let has_exception = env.exception_check(); + let cause = if has_exception.is_ok() && has_exception.unwrap() { + let cause = env.exception_occurred().expect("Couldn't get exception occurred"); + env.exception_clear().expect("Could'n clear exception occurred"); + Some(cause) + } else { + None + }; + java_core_exception.throw_parse_error(env, message, cause); null_mut() } pub fn throw_transform_error<'local, 'a>(env: &mut JNIEnv<'local>, message: &'a str) -> jobject { - unsafe { - JAVA_CORE_EXCEPTION - .as_ref() - .unwrap() - .throw_transform_error(env, message); - } + let java_core_exception = unsafe { JAVA_CORE_EXCEPTION.as_ref().unwrap() }; + let has_exception = env.exception_check(); + let cause = if has_exception.is_ok() && has_exception.unwrap() { + let cause = env.exception_occurred().expect("Couldn't get exception occurred"); + env.exception_clear().expect("Could'n clear exception occurred"); + Some(cause) + } else { + None + }; + java_core_exception.throw_transform_error(env, message, cause); null_mut() } pub fn throw_transpile_error<'local, 'a>(env: &mut JNIEnv<'local>, message: &'a str) -> jobject { - unsafe { - JAVA_CORE_EXCEPTION - .as_ref() - .unwrap() - .throw_transpile_error(env, message); - } + let java_core_exception = unsafe { JAVA_CORE_EXCEPTION.as_ref().unwrap() }; + let has_exception = env.exception_check(); + let cause = if has_exception.is_ok() && has_exception.unwrap() { + let cause = env.exception_occurred().expect("Couldn't get exception occurred"); + env.exception_clear().expect("Could'n clear exception occurred"); + Some(cause) + } else { + None + }; + java_core_exception.throw_transpile_error(env, message, cause); null_mut() } diff --git a/src/main/java/com/caoccao/javet/swc4j/exceptions/Swc4jCoreException.java b/src/main/java/com/caoccao/javet/swc4j/exceptions/Swc4jCoreException.java index 107dbc72..900b8a53 100644 --- a/src/main/java/com/caoccao/javet/swc4j/exceptions/Swc4jCoreException.java +++ b/src/main/java/com/caoccao/javet/swc4j/exceptions/Swc4jCoreException.java @@ -44,10 +44,10 @@ public static Swc4jCoreException featureNotSupported(String feature) { } /** - * Parse error. + * Creates a new parse error with the given message. * - * @param message the message - * @return the swc4j core exception + * @param message the error message + * @return a new Swc4jCoreException with the given message * @since 0.1.0 */ public static Swc4jCoreException parseError(String message) { @@ -55,9 +55,21 @@ public static Swc4jCoreException parseError(String message) { } /** - * Transform error. + * Creates a new parse error with the given message and cause. + * + * @param message the error message + * @param cause the cause of the error + * @return a new Swc4jCoreException with the given message and cause + * @since 1.0.0 + */ + public static Swc4jCoreException parseError(String message, Throwable cause) { + return new Swc4jCoreException(message, cause); + } + + /** + * Creates a new transform error with the given message. * - * @param message the message + * @param message the error message * @return the swc4j core exception * @since 1.0.0 */ @@ -66,13 +78,37 @@ public static Swc4jCoreException transformError(String message) { } /** - * Transpile error. + * Creates a new transform error with the given message and cause. * - * @param message the message + * @param message the error message + * @param cause the cause of the error + * @return a new Swc4jCoreException with the given message and cause + * @since 1.0.0 + */ + public static Swc4jCoreException transformError(String message, Throwable cause) { + return new Swc4jCoreException(message, cause); + } + + /** + * Creates a new transpile error with the given message. + * + * @param message the error message * @return the swc4j core exception * @since 0.1.0 */ public static Swc4jCoreException transpileError(String message) { return new Swc4jCoreException(message); } + + /** + * Creates a new transpile error with the given message and cause. + * + * @param message the error message + * @param cause the cause of the error + * @return a new Swc4jCoreException with the given message and cause + * @since 1.0.0 + */ + public static Swc4jCoreException transpileError(String message, Throwable cause) { + return new Swc4jCoreException(message, cause); + } } diff --git a/src/main/java/com/caoccao/javet/swc4j/plugins/Swc4jPluginHost.java b/src/main/java/com/caoccao/javet/swc4j/plugins/Swc4jPluginHost.java index aa28e814..b8eca70f 100644 --- a/src/main/java/com/caoccao/javet/swc4j/plugins/Swc4jPluginHost.java +++ b/src/main/java/com/caoccao/javet/swc4j/plugins/Swc4jPluginHost.java @@ -45,17 +45,12 @@ public List getPlugins() { @Override public boolean process(ISwc4jAstProgram program) { - try { - for (ISwc4jPlugin plugin : plugins) { - if (plugin.process(program) != Swc4jPluginResponse.OkAndContinue) { - return false; - } + for (ISwc4jPlugin plugin : plugins) { + if (plugin.process(program) != Swc4jPluginResponse.OkAndContinue) { + return false; } - return true; - } catch (Throwable t) { - t.printStackTrace(System.err); - return false; } + return true; } public Swc4jPluginHost remove(ISwc4jPlugin... plugins) { diff --git a/src/main/java/com/caoccao/javet/swc4j/plugins/jsfuck/Swc4jPluginHostJsFuckDecoder.java b/src/main/java/com/caoccao/javet/swc4j/plugins/jsfuck/Swc4jPluginHostJsFuckDecoder.java index bec756c4..4a3476b3 100644 --- a/src/main/java/com/caoccao/javet/swc4j/plugins/jsfuck/Swc4jPluginHostJsFuckDecoder.java +++ b/src/main/java/com/caoccao/javet/swc4j/plugins/jsfuck/Swc4jPluginHostJsFuckDecoder.java @@ -36,20 +36,15 @@ public int getMaxIteration() { @Override public boolean process(ISwc4jAstProgram program) { - try { - Swc4jPluginVisitorJsFuckDecoder jsFuckDecoder = new Swc4jPluginVisitorJsFuckDecoder(); - for (int i = 0; i < maxIteration; i++) { - jsFuckDecoder.reset(); - program.visit(jsFuckDecoder); - if (jsFuckDecoder.getCount() == 0) { - break; - } + Swc4jPluginVisitorJsFuckDecoder jsFuckDecoder = new Swc4jPluginVisitorJsFuckDecoder(); + for (int i = 0; i < maxIteration; i++) { + jsFuckDecoder.reset(); + program.visit(jsFuckDecoder); + if (jsFuckDecoder.getCount() == 0) { + break; } - return true; - } catch (Throwable t) { - t.printStackTrace(System.err); - return false; } + return true; } public void setMaxIteration(int maxIteration) { diff --git a/src/test/java/com/caoccao/javet/swc4j/plugins/TestSwc4jPluginHost.java b/src/test/java/com/caoccao/javet/swc4j/plugins/TestSwc4jPluginHost.java index 6a4a98e1..ee1dfcc6 100644 --- a/src/test/java/com/caoccao/javet/swc4j/plugins/TestSwc4jPluginHost.java +++ b/src/test/java/com/caoccao/javet/swc4j/plugins/TestSwc4jPluginHost.java @@ -80,10 +80,11 @@ public Swc4jAstVisitorResponse visitScript(Swc4jAstScript node) { }; swc4j.parse(code, jsScriptParseOptions .setPluginHost(new Swc4jPluginHost().add(new Swc4jPluginVisitors(SimpleList.of(visitor))))); - // TODO -// fail("Failed to throw exception."); - } catch (Throwable t) { -// t.printStackTrace(); + fail("Failed to throw exception."); + } catch (Swc4jCoreException e) { + assertEquals("Couldn't call boolean process() because Java exception was thrown", e.getMessage()); + assertInstanceOf(RuntimeException.class, e.getCause()); + assertEquals("Test", e.getCause().getMessage()); } } @@ -131,6 +132,26 @@ public void testTransformScriptCount() { }); } + @Test + public void testTransformWithException() { + String code = "1 + 1"; + try { + Swc4jAstVisitor visitor = new Swc4jAstVisitor() { + @Override + public Swc4jAstVisitorResponse visitScript(Swc4jAstScript node) { + throw new RuntimeException("Test"); + } + }; + swc4j.transform(code, jsScriptTransformOptions + .setPluginHost(new Swc4jPluginHost().add(new Swc4jPluginVisitors(SimpleList.of(visitor))))); + fail("Failed to throw exception."); + } catch (Swc4jCoreException e) { + assertEquals("Couldn't call boolean process() because Java exception was thrown", e.getMessage()); + assertInstanceOf(RuntimeException.class, e.getCause()); + assertEquals("Test", e.getCause().getMessage()); + } + } + @Test public void testTranspileModuleCount() { String code = "import a from 'a'; a + 1;"; @@ -174,4 +195,24 @@ public void testTranspileScriptCount() { } }); } + + @Test + public void testTranspileWithException() { + String code = "1 + 1"; + try { + Swc4jAstVisitor visitor = new Swc4jAstVisitor() { + @Override + public Swc4jAstVisitorResponse visitScript(Swc4jAstScript node) { + throw new RuntimeException("Test"); + } + }; + swc4j.transpile(code, jsScriptTranspileOptions + .setPluginHost(new Swc4jPluginHost().add(new Swc4jPluginVisitors(SimpleList.of(visitor))))); + fail("Failed to throw exception."); + } catch (Swc4jCoreException e) { + assertEquals("Couldn't call boolean process() because Java exception was thrown", e.getMessage()); + assertInstanceOf(RuntimeException.class, e.getCause()); + assertEquals("Test", e.getCause().getMessage()); + } + } }