Skip to content

Commit df4e81b

Browse files
authored
fix: select correct runtime when calling from different threads and improve error message (#1906)
1 parent 3efa062 commit df4e81b

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

test-app/runtime/src/main/cpp/NativeScriptException.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,34 @@ void NativeScriptException::Init() {
143143
assert(NATIVESCRIPTEXCEPTION_GET_MESSAGE_METHOD_ID != nullptr);
144144
}
145145

146+
std::string NativeScriptException::ToString() const {
147+
std::stringstream ss;
148+
if (!m_javaException.IsNull()) {
149+
JEnv env;
150+
std::string message = GetExceptionMessage(env, m_javaException);
151+
std::string stackTrace = GetExceptionStackTrace(env, m_javaException);
152+
ss << "Java Exception: " << message << "\n" << stackTrace;
153+
} else if (m_javascriptException != nullptr) {
154+
ss << "JavaScript Exception: " << m_message << "\n" << m_stackTrace;
155+
} else if (!m_message.empty()) {
156+
ss << "Exception Message: " << m_message << "\n" << m_stackTrace;
157+
} else {
158+
ss << "No exception information available.";
159+
}
160+
return ss.str();
161+
}
162+
163+
std::string NativeScriptException::GetErrorMessage() const {
164+
if(!m_javaException.IsNull()) {
165+
JEnv env;
166+
return GetExceptionMessage(env, m_javaException);
167+
} else if (m_javascriptException != nullptr) {
168+
return m_message;
169+
} else {
170+
return m_message.empty() ? "No exception message available." : m_message;
171+
}
172+
}
173+
146174
// ON V8 UNCAUGHT EXCEPTION
147175
void NativeScriptException::OnUncaughtError(Local<Message> message, Local<Value> error) {
148176
string errorMessage = GetErrorMessage(message, error);
@@ -375,7 +403,7 @@ string NativeScriptException::GetErrorStackTrace(const Local<StackTrace>& stackT
375403
return ss.str();
376404
}
377405

378-
string NativeScriptException::GetExceptionMessage(JEnv& env, jthrowable exception) {
406+
string NativeScriptException::GetExceptionMessage(JEnv& env, jthrowable exception) const {
379407
string errMsg;
380408
JniLocalRef msg(env.CallStaticObjectMethod(NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_GET_MESSAGE_METHOD_ID, exception));
381409

@@ -388,7 +416,7 @@ string NativeScriptException::GetExceptionMessage(JEnv& env, jthrowable exceptio
388416
return errMsg;
389417
}
390418

391-
string NativeScriptException::GetExceptionStackTrace(JEnv& env, jthrowable exception) {
419+
string NativeScriptException::GetExceptionStackTrace(JEnv& env, jthrowable exception) const {
392420
string errStackTrace;
393421
JniLocalRef msg(env.CallStaticObjectMethod(NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_GET_STACK_TRACE_AS_STRING_METHOD_ID, exception));
394422

test-app/runtime/src/main/cpp/NativeScriptException.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ class NativeScriptException {
3333
void ReThrowToV8();
3434
void ReThrowToJava();
3535

36+
std::string ToString() const;
37+
std::string GetErrorMessage() const;
38+
3639
static void Init();
3740

3841
/*
@@ -54,12 +57,12 @@ class NativeScriptException {
5457
/*
5558
* Gets java exception message from jthrowable
5659
*/
57-
std::string GetExceptionMessage(JEnv& env, jthrowable exception);
60+
std::string GetExceptionMessage(JEnv& env, jthrowable exception) const;
5861

5962
/*
6063
* Gets java exception stack trace from jthrowable
6164
*/
62-
std::string GetExceptionStackTrace(JEnv& env, jthrowable exception);
65+
std::string GetExceptionStackTrace(JEnv& env, jthrowable exception) const;
6366

6467
/*
6568
* Gets the member m_javaException, wraps it and creates a javascript error object from it

test-app/runtime/src/main/cpp/ObjectManager.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,23 @@ JniLocalRef ObjectManager::GetJavaObjectByJsObject(
105105
JSInstanceInfo* jsInstanceInfo = GetJSInstanceInfo(object);
106106

107107
if (jsInstanceInfo != nullptr) {
108+
jweak existingObject;
109+
try {
110+
existingObject = GetJavaObjectByID(jsInstanceInfo->JavaObjectID);
111+
} catch (const NativeScriptException& e) {
112+
// this captures usually the error
113+
auto className = GetClassName(jsInstanceInfo->ObjectClazz);
114+
throw NativeScriptException("Failed to get Java object by ID. id=" +
115+
std::to_string(jsInstanceInfo->JavaObjectID) +
116+
", class=" + className + ". " +
117+
e.GetErrorMessage());
118+
}
108119
if (m_useGlobalRefs) {
109-
JniLocalRef javaObject(GetJavaObjectByID(jsInstanceInfo->JavaObjectID),
110-
true);
120+
JniLocalRef javaObject(existingObject, true);
111121
return javaObject;
112122
} else {
113123
JEnv env;
114-
JniLocalRef javaObject(
115-
env.NewLocalRef(GetJavaObjectByID(jsInstanceInfo->JavaObjectID)));
124+
JniLocalRef javaObject(env.NewLocalRef(existingObject));
116125
return javaObject;
117126
}
118127
}

test-app/runtime/src/main/java/com/tns/Runtime.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,8 @@ public static Object callJSMethodWithDelay(Object javaObject, String methodName,
12461246
public static Object callJSMethod(Object javaObject, String methodName, Class<?> retType, boolean isConstructor, long delay, Object... args) throws NativeScriptException {
12471247
Runtime runtime = Runtime.getCurrentRuntime();
12481248

1249-
if (runtime == null) {
1249+
// if we're not in a runtime or the runtime we're in does not have the object, try to find the right one (this might happen if a worker fires a JS method on an object created in the main thread or another worker)
1250+
if (runtime == null || runtime.getJavaObjectID(javaObject) == null) {
12501251
runtime = getObjectRuntime(javaObject);
12511252
}
12521253

0 commit comments

Comments
 (0)