Skip to content

set "stack" property of error to js stack trace #1505

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void uncaughtException(Thread thread, Throwable ex) {
Runtime runtime = Runtime.getCurrentRuntime();

if (runtime != null) {
runtime.passUncaughtExceptionToJs(ex, ex.getMessage(), stackTraceErrorMessage);
runtime.passUncaughtExceptionToJs(ex, ex.getMessage(), Runtime.getJSStackTrace(ex), stackTraceErrorMessage);
}
} catch (Throwable t) {
if (Util.isDebuggableApp(context)) {
Expand Down
7 changes: 5 additions & 2 deletions test-app/runtime/src/main/cpp/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ bool Runtime::TryCallGC() {
return success;
}

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

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

//pass err to JS
NativeScriptException::CallJsFuncWithErr(errObj, isDiscarded);
Expand Down
2 changes: 1 addition & 1 deletion test-app/runtime/src/main/cpp/Runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Runtime {
void AdjustAmountOfExternalAllocatedMemory();
bool NotifyGC(JNIEnv* env, jobject obj);
bool TryCallGC();
void PassExceptionToJsNative(JNIEnv* env, jobject obj, jthrowable exception, jstring message, jstring stackTrace, jboolean isDiscarded);
void PassExceptionToJsNative(JNIEnv* env, jobject obj, jthrowable exception, jstring message, jstring fullStackTrace, jstring jsStackTrace, jboolean isDiscarded);
void PassUncaughtExceptionFromWorkerToMainHandler(v8::Local<v8::String> message, v8::Local<v8::String> stackTrace, v8::Local<v8::String> filename, int lineno);
void ClearStartupData(JNIEnv* env, jobject obj);
void DestroyRuntime();
Expand Down
7 changes: 7 additions & 0 deletions test-app/runtime/src/main/cpp/V8StringConstants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ Local<String> V8StringConstants::GetNativeException(Isolate* isolate) {
return Local<String>::New(isolate, *consts->NATIVE_EXCEPTION_PERSISTENT);
}

Local<String> V8StringConstants::GetStack(Isolate* isolate) {
auto consts = GetConstantsForIsolate(isolate);

return Local<String>::New(isolate, *consts->STACK_PERSISTENT);
}

Local<String> V8StringConstants::GetStackTrace(Isolate* isolate) {
auto consts = GetConstantsForIsolate(isolate);

Expand Down Expand Up @@ -130,6 +136,7 @@ const string V8StringConstants::NULL_NODE_NAME = "nullNode";
const string V8StringConstants::IS_PROTOTYPE_IMPLEMENTATION_OBJECT = "__isPrototypeImplementationObject";
const string V8StringConstants::NATIVE_EXCEPTION = "nativeException";
const string V8StringConstants::STACK_TRACE = "stackTrace";
const string V8StringConstants::STACK = "stack";
const string V8StringConstants::LONG_NUMBER = "NativeScriptLongNumber";
const string V8StringConstants::PROTOTYPE = "prototype";
const string V8StringConstants::SUPER = "super";
Expand Down
7 changes: 7 additions & 0 deletions test-app/runtime/src/main/cpp/V8StringConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class V8StringConstants {

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

static v8::Local<v8::String> GetStack(v8::Isolate* isolate);

static v8::Local<v8::String> GetStackTrace(v8::Isolate* isolate);

static v8::Local<v8::String> GetLongNumber(v8::Isolate* isolate);
Expand Down Expand Up @@ -52,6 +54,7 @@ class V8StringConstants {
static const std::string NULL_NODE_NAME;
static const std::string IS_PROTOTYPE_IMPLEMENTATION_OBJECT;
static const std::string NATIVE_EXCEPTION;
static const std::string STACK;
static const std::string STACK_TRACE;
static const std::string LONG_NUMBER;
static const std::string PROTOTYPE;
Expand Down Expand Up @@ -96,6 +99,8 @@ class V8StringConstants {
str = String::NewFromUtf8(isolate, NATIVE_EXCEPTION.c_str()).ToLocalChecked();
NATIVE_EXCEPTION_PERSISTENT = new Persistent<String>(isolate, str);

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

str = String::NewFromUtf8(isolate, STACK_TRACE.c_str()).ToLocalChecked();
STACK_TRACE_PERSISTENT = new Persistent<String>(isolate, str);
Expand Down Expand Up @@ -151,6 +156,7 @@ class V8StringConstants {
NULL_NODE_NAME_PERSISTENT->Reset();
IS_PROTOTYPE_IMPLEMENTATION_OBJECT_PERSISTENT->Reset();
NATIVE_EXCEPTION_PERSISTENT->Reset();
STACK_PERSISTENT->Reset();
STACK_TRACE_PERSISTENT->Reset();
LONG_NUMBER_PERSISTENT->Reset();
PROTOTYPE_PERSISTENT->Reset();
Expand All @@ -171,6 +177,7 @@ class V8StringConstants {
v8::Persistent<v8::String>* NULL_NODE_NAME_PERSISTENT;
v8::Persistent<v8::String>* IS_PROTOTYPE_IMPLEMENTATION_OBJECT_PERSISTENT;
v8::Persistent<v8::String>* NATIVE_EXCEPTION_PERSISTENT;
v8::Persistent<v8::String>* STACK_PERSISTENT;
v8::Persistent<v8::String>* STACK_TRACE_PERSISTENT;
v8::Persistent<v8::String>* LONG_NUMBER_PERSISTENT;
v8::Persistent<v8::String>* PROTOTYPE_PERSISTENT;
Expand Down
4 changes: 2 additions & 2 deletions test-app/runtime/src/main/cpp/com_tns_Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_unlock(JNIEnv* env, jobject obj,
}
}

extern "C" JNIEXPORT void Java_com_tns_Runtime_passExceptionToJsNative(JNIEnv* env, jobject obj, jint runtimeId, jthrowable exception, jstring message, jstring stackTrace, jboolean isDiscarded) {
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) {
auto runtime = TryGetRuntime(runtimeId);
if (runtime == nullptr) {
return;
Expand All @@ -256,7 +256,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_passExceptionToJsNative(JNIEnv* e
v8::HandleScope handleScope(isolate);

try {
runtime->PassExceptionToJsNative(env, obj, exception, message, stackTrace, isDiscarded);
runtime->PassExceptionToJsNative(env, obj, exception, message, fullStackTrace, jsStackTrace, isDiscarded);
} catch (NativeScriptException& e) {
e.ReThrowToJava();
} catch (std::exception e) {
Expand Down
21 changes: 15 additions & 6 deletions test-app/runtime/src/main/java/com/tns/Runtime.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private native void initNativeScript(int runtimeId, String filesPath, String nat

private native void unlock(int runtimeId);

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

private native void clearStartupData(int runtimeId);

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

private static native void ResetDateTimeConfigurationCache(int runtimeId);

void passUncaughtExceptionToJs(Throwable ex, String message, String stackTrace) {
passExceptionToJsNative(getRuntimeId(), ex, message, stackTrace, false);
void passUncaughtExceptionToJs(Throwable ex, String message, String fullStackTrace, String jsStackTrace) {
passExceptionToJsNative(getRuntimeId(), ex, message, fullStackTrace, jsStackTrace, false);
}

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

public static void passSuppressedExceptionToJs(Throwable ex, String methodName) {
Expand Down Expand Up @@ -274,6 +274,14 @@ private static String getStackTraceOnly(String content) {
return result;
}

public static String getJSStackTrace(Throwable ex) {
if (ex instanceof NativeScriptException) {
return ((NativeScriptException) ex).getIncomingStackTrace();
} else {
return null;
}
}

public static String getStackTraceErrorMessage(Throwable ex) {
String content;
java.io.PrintStream ps = null;
Expand All @@ -285,9 +293,10 @@ public static String getStackTraceErrorMessage(Throwable ex) {

try {
content = baos.toString("US-ASCII");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be UTF-8?

if (ex instanceof NativeScriptException) {
String jsStackTrace = Runtime.getJSStackTrace(ex);
if (jsStackTrace != null) {
content = getStackTraceOnly(content);
content = ((NativeScriptException) ex).getIncomingStackTrace() + content;
content = jsStackTrace + content;
}
} catch (java.io.UnsupportedEncodingException e) {
content = e.getMessage();
Expand Down