Skip to content

Commit c2ee6e7

Browse files
authored
Merge pull request #1505 from NativeScript/trifonov/setting-error-stack
set "stack" property of error to js stack trace
2 parents c7c84c5 + 9b4ebf1 commit c2ee6e7

File tree

7 files changed

+38
-12
lines changed

7 files changed

+38
-12
lines changed

test-app/app/src/main/java/com/tns/NativeScriptUncaughtExceptionHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void uncaughtException(Thread thread, Throwable ex) {
3131
Runtime runtime = Runtime.getCurrentRuntime();
3232

3333
if (runtime != null) {
34-
runtime.passUncaughtExceptionToJs(ex, ex.getMessage(), stackTraceErrorMessage);
34+
runtime.passUncaughtExceptionToJs(ex, ex.getMessage(), Runtime.getJSStackTrace(ex), stackTraceErrorMessage);
3535
}
3636
} catch (Throwable t) {
3737
if (Util.isDebuggableApp(context)) {

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ bool Runtime::TryCallGC() {
368368
return success;
369369
}
370370

371-
void Runtime::PassExceptionToJsNative(JNIEnv* env, jobject obj, jthrowable exception, jstring message, jstring stackTrace, jboolean isDiscarded) {
371+
void Runtime::PassExceptionToJsNative(JNIEnv* env, jobject obj, jthrowable exception, jstring message, jstring fullStackTrace, jstring jsStackTrace, jboolean isDiscarded) {
372372
auto isolate = m_isolate;
373373

374374
string errMsg = ArgConverter::jstringToString(message);
@@ -391,7 +391,10 @@ void Runtime::PassExceptionToJsNative(JNIEnv* env, jobject obj, jthrowable excep
391391
//create a JS error object
392392
auto context = isolate->GetCurrentContext();
393393
errObj->Set(context, V8StringConstants::GetNativeException(isolate), nativeExceptionObject);
394-
errObj->Set(context, V8StringConstants::GetStackTrace(isolate), ArgConverter::jstringToV8String(isolate, stackTrace));
394+
errObj->Set(context, V8StringConstants::GetStackTrace(isolate), ArgConverter::jstringToV8String(isolate, fullStackTrace));
395+
if (jsStackTrace != NULL) {
396+
errObj->Set(context, V8StringConstants::GetStack(isolate), ArgConverter::jstringToV8String(isolate, jsStackTrace));
397+
}
395398

396399
//pass err to JS
397400
NativeScriptException::CallJsFuncWithErr(errObj, isDiscarded);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class Runtime {
5353
void AdjustAmountOfExternalAllocatedMemory();
5454
bool NotifyGC(JNIEnv* env, jobject obj);
5555
bool TryCallGC();
56-
void PassExceptionToJsNative(JNIEnv* env, jobject obj, jthrowable exception, jstring message, jstring stackTrace, jboolean isDiscarded);
56+
void PassExceptionToJsNative(JNIEnv* env, jobject obj, jthrowable exception, jstring message, jstring fullStackTrace, jstring jsStackTrace, jboolean isDiscarded);
5757
void PassUncaughtExceptionFromWorkerToMainHandler(v8::Local<v8::String> message, v8::Local<v8::String> stackTrace, v8::Local<v8::String> filename, int lineno);
5858
void ClearStartupData(JNIEnv* env, jobject obj);
5959
void DestroyRuntime();

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ Local<String> V8StringConstants::GetNativeException(Isolate* isolate) {
5151
return Local<String>::New(isolate, *consts->NATIVE_EXCEPTION_PERSISTENT);
5252
}
5353

54+
Local<String> V8StringConstants::GetStack(Isolate* isolate) {
55+
auto consts = GetConstantsForIsolate(isolate);
56+
57+
return Local<String>::New(isolate, *consts->STACK_PERSISTENT);
58+
}
59+
5460
Local<String> V8StringConstants::GetStackTrace(Isolate* isolate) {
5561
auto consts = GetConstantsForIsolate(isolate);
5662

@@ -130,6 +136,7 @@ const string V8StringConstants::NULL_NODE_NAME = "nullNode";
130136
const string V8StringConstants::IS_PROTOTYPE_IMPLEMENTATION_OBJECT = "__isPrototypeImplementationObject";
131137
const string V8StringConstants::NATIVE_EXCEPTION = "nativeException";
132138
const string V8StringConstants::STACK_TRACE = "stackTrace";
139+
const string V8StringConstants::STACK = "stack";
133140
const string V8StringConstants::LONG_NUMBER = "NativeScriptLongNumber";
134141
const string V8StringConstants::PROTOTYPE = "prototype";
135142
const string V8StringConstants::SUPER = "super";

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class V8StringConstants {
2121

2222
static v8::Local<v8::String> GetNativeException(v8::Isolate* isolate);
2323

24+
static v8::Local<v8::String> GetStack(v8::Isolate* isolate);
25+
2426
static v8::Local<v8::String> GetStackTrace(v8::Isolate* isolate);
2527

2628
static v8::Local<v8::String> GetLongNumber(v8::Isolate* isolate);
@@ -52,6 +54,7 @@ class V8StringConstants {
5254
static const std::string NULL_NODE_NAME;
5355
static const std::string IS_PROTOTYPE_IMPLEMENTATION_OBJECT;
5456
static const std::string NATIVE_EXCEPTION;
57+
static const std::string STACK;
5558
static const std::string STACK_TRACE;
5659
static const std::string LONG_NUMBER;
5760
static const std::string PROTOTYPE;
@@ -96,6 +99,8 @@ class V8StringConstants {
9699
str = String::NewFromUtf8(isolate, NATIVE_EXCEPTION.c_str()).ToLocalChecked();
97100
NATIVE_EXCEPTION_PERSISTENT = new Persistent<String>(isolate, str);
98101

102+
str = String::NewFromUtf8(isolate, STACK.c_str()).ToLocalChecked();
103+
STACK_PERSISTENT = new Persistent<String>(isolate, str);
99104

100105
str = String::NewFromUtf8(isolate, STACK_TRACE.c_str()).ToLocalChecked();
101106
STACK_TRACE_PERSISTENT = new Persistent<String>(isolate, str);
@@ -151,6 +156,7 @@ class V8StringConstants {
151156
NULL_NODE_NAME_PERSISTENT->Reset();
152157
IS_PROTOTYPE_IMPLEMENTATION_OBJECT_PERSISTENT->Reset();
153158
NATIVE_EXCEPTION_PERSISTENT->Reset();
159+
STACK_PERSISTENT->Reset();
154160
STACK_TRACE_PERSISTENT->Reset();
155161
LONG_NUMBER_PERSISTENT->Reset();
156162
PROTOTYPE_PERSISTENT->Reset();
@@ -171,6 +177,7 @@ class V8StringConstants {
171177
v8::Persistent<v8::String>* NULL_NODE_NAME_PERSISTENT;
172178
v8::Persistent<v8::String>* IS_PROTOTYPE_IMPLEMENTATION_OBJECT_PERSISTENT;
173179
v8::Persistent<v8::String>* NATIVE_EXCEPTION_PERSISTENT;
180+
v8::Persistent<v8::String>* STACK_PERSISTENT;
174181
v8::Persistent<v8::String>* STACK_TRACE_PERSISTENT;
175182
v8::Persistent<v8::String>* LONG_NUMBER_PERSISTENT;
176183
v8::Persistent<v8::String>* PROTOTYPE_PERSISTENT;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_unlock(JNIEnv* env, jobject obj,
245245
}
246246
}
247247

248-
extern "C" JNIEXPORT void Java_com_tns_Runtime_passExceptionToJsNative(JNIEnv* env, jobject obj, jint runtimeId, jthrowable exception, jstring message, jstring stackTrace, jboolean isDiscarded) {
248+
extern "C" JNIEXPORT void Java_com_tns_Runtime_passExceptionToJsNative(JNIEnv* env, jobject obj, jint runtimeId, jthrowable exception, jstring message, jstring fullStackTrace, jstring jsStackTrace, jboolean isDiscarded) {
249249
auto runtime = TryGetRuntime(runtimeId);
250250
if (runtime == nullptr) {
251251
return;
@@ -256,7 +256,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_passExceptionToJsNative(JNIEnv* e
256256
v8::HandleScope handleScope(isolate);
257257

258258
try {
259-
runtime->PassExceptionToJsNative(env, obj, exception, message, stackTrace, isDiscarded);
259+
runtime->PassExceptionToJsNative(env, obj, exception, message, fullStackTrace, jsStackTrace, isDiscarded);
260260
} catch (NativeScriptException& e) {
261261
e.ReThrowToJava();
262262
} catch (std::exception e) {

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ private native void initNativeScript(int runtimeId, String filesPath, String nat
5858

5959
private native void unlock(int runtimeId);
6060

61-
private native void passExceptionToJsNative(int runtimeId, Throwable ex, String message, String stackTrace, boolean isDiscarded);
61+
private native void passExceptionToJsNative(int runtimeId, Throwable ex, String message, String fullStackTrace, String jsStackTrace, boolean isDiscarded);
6262

6363
private native void clearStartupData(int runtimeId);
6464

@@ -78,15 +78,15 @@ private native void initNativeScript(int runtimeId, String filesPath, String nat
7878

7979
private static native void ResetDateTimeConfigurationCache(int runtimeId);
8080

81-
void passUncaughtExceptionToJs(Throwable ex, String message, String stackTrace) {
82-
passExceptionToJsNative(getRuntimeId(), ex, message, stackTrace, false);
81+
void passUncaughtExceptionToJs(Throwable ex, String message, String fullStackTrace, String jsStackTrace) {
82+
passExceptionToJsNative(getRuntimeId(), ex, message, fullStackTrace, jsStackTrace, false);
8383
}
8484

8585
void passDiscardedExceptionToJs(Throwable ex, String prefix) {
8686
//String message = prefix + ex.getMessage();
8787
// we'd better not prefix the error with something like - Error on "main" thread for reportSupressedException
8888
// as it doesn't seem very useful for the users
89-
passExceptionToJsNative(getRuntimeId(), ex, ex.getMessage(), Runtime.getStackTraceErrorMessage(ex), true);
89+
passExceptionToJsNative(getRuntimeId(), ex, ex.getMessage(), Runtime.getStackTraceErrorMessage(ex), Runtime.getJSStackTrace(ex), true);
9090
}
9191

9292
public static void passSuppressedExceptionToJs(Throwable ex, String methodName) {
@@ -274,6 +274,14 @@ private static String getStackTraceOnly(String content) {
274274
return result;
275275
}
276276

277+
public static String getJSStackTrace(Throwable ex) {
278+
if (ex instanceof NativeScriptException) {
279+
return ((NativeScriptException) ex).getIncomingStackTrace();
280+
} else {
281+
return null;
282+
}
283+
}
284+
277285
public static String getStackTraceErrorMessage(Throwable ex) {
278286
String content;
279287
java.io.PrintStream ps = null;
@@ -285,9 +293,10 @@ public static String getStackTraceErrorMessage(Throwable ex) {
285293

286294
try {
287295
content = baos.toString("US-ASCII");
288-
if (ex instanceof NativeScriptException) {
296+
String jsStackTrace = Runtime.getJSStackTrace(ex);
297+
if (jsStackTrace != null) {
289298
content = getStackTraceOnly(content);
290-
content = ((NativeScriptException) ex).getIncomingStackTrace() + content;
299+
content = jsStackTrace + content;
291300
}
292301
} catch (java.io.UnsupportedEncodingException e) {
293302
content = e.getMessage();

0 commit comments

Comments
 (0)