Skip to content

Commit

Permalink
🦄 refactor: Revise error handling 4
Browse files Browse the repository at this point in the history
  • Loading branch information
caoccao committed Aug 1, 2024
1 parent e1ea8c8 commit fe1ddf3
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 61 deletions.
109 changes: 80 additions & 29 deletions rust/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 {
Expand All @@ -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<JThrowable<'a>>,
) {
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<JThrowable<'a>>,
) {
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<JThrowable<'a>>,
) {
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");
}
}

Expand All @@ -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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,32 @@ 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) {
return new Swc4jCoreException(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
*/
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,12 @@ public List<ISwc4jPlugin> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}

Expand Down Expand Up @@ -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;";
Expand Down Expand Up @@ -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());
}
}
}

0 comments on commit fe1ddf3

Please sign in to comment.