1313#include < sstream>
1414#include < nan.h>
1515
16- #define DYNAMIC_PROXY_NO_SUCH_METHOD_ERROR -1
17- #define DYNAMIC_PROXY_NOT_A_FUNCTION_ERROR -2
18- #define DYNAMIC_PROXY_NO_ENV_ERROR -3
16+ #define DYNAMIC_PROXY_JS_ERROR -4
1917
2018long v8ThreadId;
2119
@@ -999,6 +997,15 @@ NAN_METHOD(Java::instanceOf) {
999997void EIO_CallJs (uv_work_t * req) {
1000998}
1001999
1000+ jthrowable newThrowable (JNIEnv* env, const char * excClassName, std::string msg) {
1001+ jclass newExcCls = env->FindClass (excClassName);
1002+ jthrowable throwable = env->ExceptionOccurred ();
1003+ if (throwable != NULL ) {
1004+ return throwable; // this should only be Errors, according to the docs
1005+ }
1006+ env->ThrowNew (newExcCls, msg.c_str ());
1007+ }
1008+
10021009#if NODE_MINOR_VERSION >= 10
10031010void EIO_AfterCallJs (uv_work_t * req, int status) {
10041011#else
@@ -1013,9 +1020,10 @@ void EIO_AfterCallJs(uv_work_t* req) {
10131020 JNIEnv* env;
10141021 int ret = dynamicProxyData->java ->getJvm ()->GetEnv ((void **)&env, JNI_VERSION_1_6);
10151022 if (ret != JNI_OK) {
1016- printf (" ERROR: jvm->GetEnv returned %d\n " , ret);
1017- dynamicProxyData->done = DYNAMIC_PROXY_NO_ENV_ERROR;
1018- return ;
1023+ dynamicProxyData->throwableClass = " java/lang/IllegalStateException" ;
1024+ dynamicProxyData->throwableMessage = " Could not retrieve JNIEnv: jvm->GetEnv returned " + ret;
1025+ dynamicProxyData->done = DYNAMIC_PROXY_JS_ERROR;
1026+ return ;
10191027 }
10201028
10211029 NanScope ();
@@ -1030,11 +1038,15 @@ void EIO_AfterCallJs(uv_work_t* req) {
10301038 v8::Local<v8::Object> dynamicProxyDataFunctions = NanNew (dynamicProxyData->functions );
10311039 v8::Local<v8::Value> fnObj = dynamicProxyDataFunctions->Get (NanNew<v8::String>(dynamicProxyData->methodName .c_str ()));
10321040 if (fnObj->IsUndefined () || fnObj->IsNull ()) {
1033- dynamicProxyData->done = DYNAMIC_PROXY_NO_SUCH_METHOD_ERROR;
1041+ dynamicProxyData->throwableClass = " java/lang/NoSuchMethodError" ;
1042+ dynamicProxyData->throwableMessage = " Could not find js function " + dynamicProxyData->methodName ;
1043+ dynamicProxyData->done = DYNAMIC_PROXY_JS_ERROR;
10341044 return ;
10351045 }
10361046 if (!fnObj->IsFunction ()) {
1037- dynamicProxyData->done = DYNAMIC_PROXY_NOT_A_FUNCTION_ERROR;
1047+ dynamicProxyData->throwableClass = " java/lang/IllegalStateException" ;
1048+ dynamicProxyData->throwableMessage = dynamicProxyData->methodName + " is not a function" ;
1049+ dynamicProxyData->done = DYNAMIC_PROXY_JS_ERROR;
10381050 return ;
10391051 }
10401052
@@ -1050,8 +1062,24 @@ void EIO_AfterCallJs(uv_work_t* req) {
10501062 for (i=0 ; i<argc; i++) {
10511063 argv[i] = v8Args->Get (i);
10521064 }
1065+
1066+ v8::TryCatch tryCatch;
10531067 v8Result = fn->Call (dynamicProxyDataFunctions, argc, argv);
10541068 delete[] argv;
1069+ if (tryCatch.HasCaught ()) {
1070+ dynamicProxyData->throwableClass = " node/NodeJsException" ;
1071+ v8::String::Utf8Value stackTrace (tryCatch.StackTrace ());
1072+ if (stackTrace.length () > 0 ) {
1073+ dynamicProxyData->throwableMessage = std::string (*stackTrace);
1074+ } else {
1075+ v8::String::Utf8Value exception (tryCatch.Exception ());
1076+ dynamicProxyData->throwableMessage = std::string (*exception);
1077+ }
1078+ tryCatch.Reset ();
1079+ dynamicProxyData->done = DYNAMIC_PROXY_JS_ERROR;
1080+ return ;
1081+ }
1082+
10551083 if (!dynamicProxyDataVerify (dynamicProxyData)) {
10561084 return ;
10571085 }
@@ -1084,6 +1112,8 @@ JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs(JNIEnv *env, jo
10841112 dynamicProxyData->args = args;
10851113 dynamicProxyData->done = false ;
10861114 dynamicProxyData->result = NULL ;
1115+ dynamicProxyData->throwableClass = " " ;
1116+ dynamicProxyData->throwableMessage = " " ;
10871117
10881118 jclass methodClazz = env->FindClass (" java/lang/reflect/Method" );
10891119 jmethodID method_getName = env->GetMethodID (methodClazz, " getName" , " ()Ljava/lang/String;" );
@@ -1119,16 +1149,8 @@ JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs(JNIEnv *env, jo
11191149 env->DeleteGlobalRef (dynamicProxyData->args );
11201150 }
11211151
1122- switch (dynamicProxyData->done ) {
1123- case DYNAMIC_PROXY_NO_SUCH_METHOD_ERROR:
1124- throwNewThrowable (env, " java/lang/NoSuchMethodError" , " Could not find js function " + dynamicProxyData->methodName );
1125- break ;
1126- case DYNAMIC_PROXY_NOT_A_FUNCTION_ERROR:
1127- throwNewThrowable (env, " java/lang/IllegalStateException" , dynamicProxyData->methodName + " is not a function" );
1128- break ;
1129- case DYNAMIC_PROXY_NO_ENV_ERROR:
1130- throwNewThrowable (env, " java/lang/IllegalStateException" , " Could not retrieve JNIEnv" );
1131- break ;
1152+ if (dynamicProxyData->done == DYNAMIC_PROXY_JS_ERROR) {
1153+ throwNewThrowable (env, dynamicProxyData->throwableClass .c_str (), dynamicProxyData->throwableMessage );
11321154 }
11331155
11341156 jobject result = NULL ;
0 commit comments