@@ -23,14 +23,20 @@ NativeScriptException::NativeScriptException(const string& message)
23
23
m_javascriptException(nullptr ), m_javaException(JniLocalRef()), m_message(message) {
24
24
}
25
25
26
+ NativeScriptException::NativeScriptException (const string& message, const string& stackTrace)
27
+ :
28
+ m_javascriptException(nullptr ), m_javaException(JniLocalRef()), m_message(message), m_stackTrace(stackTrace) {
29
+ }
30
+
26
31
NativeScriptException::NativeScriptException (TryCatch& tc, const string& message)
27
32
:
28
33
m_javaException(JniLocalRef()) {
29
34
auto isolate = Isolate::GetCurrent ();
30
35
m_javascriptException = new Persistent<Value>(isolate, tc.Exception ());
31
- bool isMessageEmpty = tc.Message ().IsEmpty ();
32
- bool isExceptionEmpty = tc.Exception ().IsEmpty ();
33
- m_message = GetFullMessage (tc, isExceptionEmpty, isMessageEmpty, message);
36
+ auto ex = tc.Exception ();
37
+ m_message = GetErrorMessage (tc.Message (), ex, message);
38
+ m_stackTrace = GetErrorStackTrace (tc.Message ()->GetStackTrace ());
39
+ m_fullMessage = GetFullMessage (tc, m_message);
34
40
tc.Reset ();
35
41
}
36
42
@@ -40,9 +46,15 @@ void NativeScriptException::ReThrowToV8() {
40
46
41
47
if (m_javascriptException != nullptr ) {
42
48
errObj = Local<Value>::New (isolate, *m_javascriptException);
43
- if (errObj->IsObject () && !m_message.empty ()) {
44
- errObj.As <Object>()->Set (ArgConverter::ConvertToV8String (isolate, " fullMessage" ), ArgConverter::ConvertToV8String (isolate, m_message));
49
+ if (errObj->IsObject ()) {
50
+ if (!m_fullMessage.empty ()) {
51
+ errObj.As <Object>()->Set (ArgConverter::ConvertToV8String (isolate, " fullMessage" ), ArgConverter::ConvertToV8String (isolate, m_fullMessage));
52
+ } else if (!m_message.empty ()) {
53
+ errObj.As <Object>()->Set (ArgConverter::ConvertToV8String (isolate, " fullMessage" ), ArgConverter::ConvertToV8String (isolate, m_message));
54
+ }
45
55
}
56
+ } else if (!m_fullMessage.empty ()) {
57
+ errObj = Exception::Error (ArgConverter::ConvertToV8String (isolate, m_fullMessage));
46
58
} else if (!m_message.empty ()) {
47
59
errObj = Exception::Error (ArgConverter::ConvertToV8String (isolate, m_message));
48
60
} else if (!m_javaException.IsNull ()) {
@@ -83,22 +95,24 @@ void NativeScriptException::ReThrowToJava() {
83
95
ex = (jthrowable) exObj.Move ();
84
96
}
85
97
98
+ JniLocalRef msg (env.NewStringUTF (m_message.c_str ()));
99
+ JniLocalRef stackTrace (env.NewStringUTF (m_stackTrace.c_str ()));
100
+
86
101
if (ex == nullptr ) {
87
- JniLocalRef msg (env.NewStringUTF (m_message.c_str ()));
88
- ex = static_cast <jthrowable>(env.NewObject (NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID, (jstring) msg, reinterpret_cast <jlong>(m_javascriptException)));
102
+ ex = static_cast <jthrowable>(env.NewObject (NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID, (jstring) msg, (jstring)stackTrace, reinterpret_cast <jlong>(m_javascriptException)));
89
103
} else {
90
104
auto excClassName = objectManager->GetClassName (ex);
91
105
if (excClassName != " com/tns/NativeScriptException" ) {
92
- JniLocalRef msg (env.NewStringUTF (m_message.c_str ()));
93
- ex = static_cast <jthrowable>(env.NewObject (NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID, (jstring) msg, ex));
106
+ ex = static_cast <jthrowable>(env.NewObject (NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID, (jstring) msg, (jstring)stackTrace, ex));
94
107
}
95
108
}
96
109
} else if (!m_message.empty ()) {
97
110
JniLocalRef msg (env.NewStringUTF (m_message.c_str ()));
98
- ex = static_cast <jthrowable>(env.NewObject (NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID, (jstring) msg, (jlong) 0 ));
111
+ JniLocalRef stackTrace (env.NewStringUTF (m_stackTrace.c_str ()));
112
+ ex = static_cast <jthrowable>(env.NewObject (NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID, (jstring) msg, (jstring)stackTrace, (jlong) 0 ));
99
113
} else {
100
114
JniLocalRef msg (env.NewStringUTF (" No java exception or message provided." ));
101
- ex = static_cast <jthrowable>(env.NewObject (NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID, (jstring) msg, (jlong) 0 ));
115
+ ex = static_cast <jthrowable>(env.NewObject (NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID, (jstring) msg, (jstring) nullptr , ( jlong) 0 ));
102
116
}
103
117
env.Throw (ex);
104
118
}
@@ -115,10 +129,10 @@ void NativeScriptException::Init() {
115
129
NATIVESCRIPTEXCEPTION_CLASS = env.FindClass (" com/tns/NativeScriptException" );
116
130
assert (NATIVESCRIPTEXCEPTION_CLASS != nullptr );
117
131
118
- NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID = env.GetMethodID (NATIVESCRIPTEXCEPTION_CLASS, " <init>" , " (Ljava/lang/String;J)V" );
132
+ NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID = env.GetMethodID (NATIVESCRIPTEXCEPTION_CLASS, " <init>" , " (Ljava/lang/String;Ljava/lang/String; J)V" );
119
133
assert (NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID != nullptr );
120
134
121
- NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID = env.GetMethodID (NATIVESCRIPTEXCEPTION_CLASS, " <init>" , " (Ljava/lang/String;Ljava/lang/Throwable;)V" );
135
+ NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID = env.GetMethodID (NATIVESCRIPTEXCEPTION_CLASS, " <init>" , " (Ljava/lang/String;Ljava/lang/String;Ljava/lang/ Throwable;)V" );
122
136
assert (NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID != nullptr );
123
137
124
138
NATIVESCRIPTEXCEPTION_GET_STACK_TRACE_AS_STRING_METHOD_ID = env.GetStaticMethodID (NATIVESCRIPTEXCEPTION_CLASS, " getStackTraceAsString" , " (Ljava/lang/Throwable;)Ljava/lang/String;" );
@@ -128,8 +142,9 @@ void NativeScriptException::Init() {
128
142
// ON V8 UNCAUGHT EXCEPTION
129
143
void NativeScriptException::OnUncaughtError (Local<Message> message, Local<Value> error) {
130
144
string errorMessage = GetErrorMessage (message, error);
145
+ string stackTrace = GetErrorStackTrace (message->GetStackTrace ());
131
146
132
- NativeScriptException e (errorMessage);
147
+ NativeScriptException e (errorMessage, stackTrace );
133
148
e.ReThrowToJava ();
134
149
}
135
150
@@ -203,17 +218,31 @@ Local<Value> NativeScriptException::GetJavaExceptionFromEnv(const JniLocalRef& e
203
218
return errObj;
204
219
}
205
220
206
- string NativeScriptException::GetFullMessage (const TryCatch& tc, bool isExceptionEmpty, bool isMessageEmpty, const string& prependMessage ) {
221
+ string NativeScriptException::GetFullMessage (const TryCatch& tc, const string& jsExceptionMessage ) {
207
222
auto ex = tc.Exception ();
208
223
209
- string jsExeptionMessage;
224
+ v8::Isolate* isolate = v8::Isolate::GetCurrent ();
225
+ v8::Local<v8::Context> context = isolate->GetEnteredContext ();
210
226
211
- if (!isExceptionEmpty && !isMessageEmpty) {
212
- jsExeptionMessage = GetErrorMessage (tc.Message (), ex);
213
- }
227
+ auto message = tc.Message ();
214
228
215
229
stringstream ss;
216
- ss << endl << prependMessage << jsExeptionMessage;
230
+ ss << jsExceptionMessage;
231
+
232
+ // get script name
233
+ auto scriptResName = message->GetScriptResourceName ();
234
+
235
+ // get stack trace
236
+ string stackTraceMessage = GetErrorStackTrace (message->GetStackTrace ());
237
+
238
+ if (!scriptResName.IsEmpty () && scriptResName->IsString ()) {
239
+ ss << endl <<" File: \" " << ArgConverter::ConvertToString (scriptResName.As <String>());
240
+ } else {
241
+ ss << endl <<" File: \" <unknown>" ;
242
+ }
243
+ ss << " , line: " << message->GetLineNumber (context).ToChecked () << " , column: " << message->GetStartColumn () << endl << endl;
244
+ ss << " StackTrace: " << endl << stackTraceMessage << endl;
245
+
217
246
string loggedMessage = ss.str ();
218
247
219
248
PrintErrorMessage (loggedMessage);
@@ -266,46 +295,38 @@ void NativeScriptException::PrintErrorMessage(const string& errorMessage) {
266
295
}
267
296
}
268
297
269
- string NativeScriptException::GetErrorMessage (const Local<Message>& message, Local<Value>& error) {
298
+ string NativeScriptException::GetErrorMessage (const Local<Message>& message, Local<Value>& error, const string& prependMessage ) {
270
299
271
300
Local<String> message_text_string = message->Get ();
272
301
auto mes = ArgConverter::ConvertToString (message_text_string);
273
302
274
303
v8::Isolate* isolate = v8::Isolate::GetCurrent ();
275
304
v8::Local<v8::Context> context = isolate->GetEnteredContext ();
276
- int line_number = message->GetLineNumber (context).FromMaybe (0 );
277
305
278
306
// get whole error message from previous stack
307
+ stringstream ss;
308
+
309
+ if (prependMessage != " " ) {
310
+ ss << prependMessage << endl;
311
+ }
312
+
279
313
string errMessage;
314
+ bool hasFullErrorMessage = false ;
280
315
auto v8FullMessage = ArgConverter::ConvertToV8String (isolate, " fullMessage" );
281
316
if (error->IsObject () && error.As <Object>()->Has (context, v8FullMessage).ToChecked ()) {
317
+ hasFullErrorMessage = true ;
282
318
errMessage = ArgConverter::ConvertToString (error.As <Object>()->Get (v8FullMessage).As <String>());
319
+ ss << errMessage;
283
320
}
284
321
285
-
286
- // get current message
287
322
auto str = error->ToDetailString (context);
288
- if (str.IsEmpty ()) {
289
- str = String::NewFromUtf8 (isolate, " " );
290
- }
291
- String::Utf8Value utfError (isolate, str.FromMaybe (Local<String>()));
292
-
293
- // get script name
294
- auto scriptResName = message->GetScriptResourceName ();
295
-
296
- // get stack trace
297
- string stackTraceMessage = GetErrorStackTrace (message->GetStackTrace ());
298
-
299
- stringstream ss;
300
- ss << endl << errMessage;
301
- ss << endl << *utfError << endl;
302
- if (!scriptResName.IsEmpty () && scriptResName->IsString ()) {
303
- ss << " File: \" " << ArgConverter::ConvertToString (scriptResName.As <String>());
304
- } else {
305
- ss << " File: \" <unknown>" ;
323
+ if (!str.IsEmpty ()) {
324
+ String::Utf8Value utfError (isolate, str.FromMaybe (Local<String>()));
325
+ if (hasFullErrorMessage) {
326
+ ss << endl;
327
+ }
328
+ ss << *utfError;
306
329
}
307
- ss << " , line: " << message->GetLineNumber (context).ToChecked () << " , column: " << message->GetStartColumn () << endl << endl;
308
- ss << " StackTrace: " << endl << stackTraceMessage << endl;
309
330
310
331
return ss.str ();
311
332
}
0 commit comments