From 9096fd1cfe75eda8e43db88029fe8bdb0a213137 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Sat, 8 Feb 2025 16:33:49 +0100 Subject: [PATCH 01/24] Update V8Runtime.cpp for UncaughtException handler --- android/runtime/v8/src/native/V8Runtime.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index a5fa38068d6..3c1b4180a05 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -176,6 +176,10 @@ static void logV8Exception(Local msg, Local data) } // namespace titanium +static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { + LOGE(TAG, "Error"); +} + extern "C" { using namespace titanium; @@ -223,6 +227,7 @@ JNIEXPORT void JNICALL Java_org_appcelerator_kroll_runtime_v8_V8Runtime_nativeIn // isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException); // isolate->SetAutorunMicrotasks(false); // isolate->SetFatalErrorHandler(OnFatalError); + isolate->SetPromiseRejectCallback(_PromiseRejectCallback); isolate->SetCaptureStackTraceForUncaughtExceptions(true, 10, v8::StackTrace::kOverview); } else { isolate = V8Runtime::v8_isolate; From 2b4f484d1a683f0b82ae3e47611fdd01d848e414 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Sat, 8 Feb 2025 16:51:41 +0100 Subject: [PATCH 02/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 59 +++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index 3c1b4180a05..53f7eedcc35 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -177,6 +177,65 @@ static void logV8Exception(Local msg, Local data) } // namespace titanium static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { +// V8Util::openJSErrorDialog(V8Runtime::v8_isolate, tryCatch); +// V8Util::reportException(V8Runtime::v8_isolate, tryCatch, true); + +/* + Runtime* rt = Runtime::current(); + Isolate* isolate = rt->isolate(); +*/ + + v8::Isolate* isolate = data.GetIsolate(); + v8::Local value = data.GetValue(); + v8::PromiseRejectEvent e = data.GetEvent(); + + if (event == v8::kPromiseRejectWithNoHandler) { + if (!value.IsEmpty()) { + v8::String::Utf8Value error(isolate, value); + LOGE("Unhandled Promise Rejection: %s", *error); + } else { + LOGE("Unhandled Promise Rejection with no message",); + } + } +} + + +/* + v8::Local _context = isolate->context(); + v8::Local _promise_error; + + if (rt->m_promise_error.IsEmpty()) { + _promise_error = v8::Array::New(isolate->m_isolate); + rt->m_promise_error.Reset(isolate->m_isolate, _promise_error); + } else + _promise_error = rt->m_promise_error.Get(isolate->m_isolate); + + if (e == v8::kPromiseRejectWithNoHandler) { + v8::Local o = v8::Array::New(isolate->m_isolate); + o->Set(_context, 0, data.GetPromise()).IsJust(); + o->Set(_context, 1, data.GetValue()).IsJust(); + _promise_error->Set(_context, rt->m_promise_error_no++, o).IsJust(); + } else if (e == v8::kPromiseHandlerAddedAfterReject) { + v8::Local _promise = data.GetPromise(); + if (!_promise.IsEmpty()) { + JSArray ks = _promise_error->GetPropertyNames(_context); + int32_t len = ks->Length(); + + for (int32_t i = 0; i < len; i++) { + JSValue k = ks->Get(_context, i); + JSValue v = _promise_error->Get(_context, k); + + v8::Local o = v8::Local::Cast(v); + v = o->Get(_context, 0); + + bool e = _promise->Equals(_context, v).FromMaybe(false); + if (e) { + _promise_error->Delete(_context, k).IsJust(); + } + } + } + } +*/ LOGE(TAG, "Error"); } From 98199466596266fadcc39ee55ccd7707dbf4567a Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Sat, 8 Feb 2025 17:01:35 +0100 Subject: [PATCH 03/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 57 ++++----------------- 1 file changed, 11 insertions(+), 46 deletions(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index 53f7eedcc35..b809b58c6a7 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -179,15 +179,20 @@ static void logV8Exception(Local msg, Local data) static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { // V8Util::openJSErrorDialog(V8Runtime::v8_isolate, tryCatch); // V8Util::reportException(V8Runtime::v8_isolate, tryCatch, true); - -/* - Runtime* rt = Runtime::current(); - Isolate* isolate = rt->isolate(); -*/ - + v8::Isolate* isolate = data.GetIsolate(); + v8::Local _promise = data.GetPromise(); v8::Local value = data.GetValue(); v8::PromiseRejectEvent e = data.GetEvent(); + Local context = isolate->GetCurrentContext(); // V8Runtime::v8_isolate ? + + String::Utf8Value utf8Message(V8Runtime::v8_isolate, data->Get()); + String::Utf8Value utf8ScriptName(V8Runtime::v8_isolate, data->GetScriptResourceName()); + LOGE(TAG, *utf8Message); + LOGE(TAG, "%s @ %d >>> %s", + *utf8ScriptName, + msg->GetLineNumber(context).FromMaybe(-1), + msg->GetSourceLine(context).ToLocalChecked()); if (event == v8::kPromiseRejectWithNoHandler) { if (!value.IsEmpty()) { @@ -198,46 +203,6 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { } } } - - -/* - v8::Local _context = isolate->context(); - v8::Local _promise_error; - - if (rt->m_promise_error.IsEmpty()) { - _promise_error = v8::Array::New(isolate->m_isolate); - rt->m_promise_error.Reset(isolate->m_isolate, _promise_error); - } else - _promise_error = rt->m_promise_error.Get(isolate->m_isolate); - - if (e == v8::kPromiseRejectWithNoHandler) { - v8::Local o = v8::Array::New(isolate->m_isolate); - o->Set(_context, 0, data.GetPromise()).IsJust(); - o->Set(_context, 1, data.GetValue()).IsJust(); - _promise_error->Set(_context, rt->m_promise_error_no++, o).IsJust(); - } else if (e == v8::kPromiseHandlerAddedAfterReject) { - v8::Local _promise = data.GetPromise(); - if (!_promise.IsEmpty()) { - JSArray ks = _promise_error->GetPropertyNames(_context); - int32_t len = ks->Length(); - - for (int32_t i = 0; i < len; i++) { - JSValue k = ks->Get(_context, i); - JSValue v = _promise_error->Get(_context, k); - - v8::Local o = v8::Local::Cast(v); - v = o->Get(_context, 0); - - bool e = _promise->Equals(_context, v).FromMaybe(false); - if (e) { - _promise_error->Delete(_context, k).IsJust(); - } - } - } - } -*/ - LOGE(TAG, "Error"); -} extern "C" { From 0e09f3b733aadc1995a71236d055ab7473de5b0c Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Sat, 8 Feb 2025 17:12:29 +0100 Subject: [PATCH 04/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index b809b58c6a7..7cac69749f9 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -202,6 +202,9 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { LOGE("Unhandled Promise Rejection with no message",); } } + +// V8::TryCatch tryCatch(isolate); +// titanium::V8Util::fatalException(isolate, tryCatch); } extern "C" { From e6c000495cf9ba3013b94d11aa5fb91f532aebde Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Sun, 9 Feb 2025 14:16:12 +0100 Subject: [PATCH 05/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 24 ++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index 7cac69749f9..d5fbe1888b0 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -186,13 +186,27 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { v8::PromiseRejectEvent e = data.GetEvent(); Local context = isolate->GetCurrentContext(); // V8Runtime::v8_isolate ? + v8::Local message = v8::Exception::CreateMessage(isolate, value); + v8::String::Utf8Value utf8Message(isolate, message->Get()); + v8::String::Utf8Value utf8ScriptName(isolate, message->GetScriptResourceName()); + v8::Local sourceLine = message->GetSourceLine(context).ToLocalChecked(); + v8::String::Utf8Value utf8SourceLine(isolate, sourceLine); + +/* + // Alternative version: + String::Utf8Value utf8Message(V8Runtime::v8_isolate, data->Get()); String::Utf8Value utf8ScriptName(V8Runtime::v8_isolate, data->GetScriptResourceName()); - LOGE(TAG, *utf8Message); - LOGE(TAG, "%s @ %d >>> %s", - *utf8ScriptName, - msg->GetLineNumber(context).FromMaybe(-1), - msg->GetSourceLine(context).ToLocalChecked()); + LOGE(TAG, *utf8Message); + LOGE(TAG, "%s", *utf8ScriptName); + +*/ + + LOGE(TAG, "%s", *utf8Message); + LOGE(TAG, "%s @ %d >>> %s", + *utf8ScriptName, + message->GetLineNumber(context).FromMaybe(-1), + *utf8SourceLine); if (event == v8::kPromiseRejectWithNoHandler) { if (!value.IsEmpty()) { From 228f3cebc0edca9cc4c7252648fa9b368ab3d2ee Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Sun, 9 Feb 2025 15:36:52 +0100 Subject: [PATCH 06/24] Update V8Util.cpp --- android/runtime/v8/src/native/V8Util.cpp | 50 ++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/android/runtime/v8/src/native/V8Util.cpp b/android/runtime/v8/src/native/V8Util.cpp index 18de9f46732..0deca30a7fb 100644 --- a/android/runtime/v8/src/native/V8Util.cpp +++ b/android/runtime/v8/src/native/V8Util.cpp @@ -157,6 +157,52 @@ void V8Util::reportException(Isolate* isolate, TryCatch &tryCatch, bool showLine LOGE(EXC_TAG, *error); } +void V8Util::reportRejection(Isolate* isolate, TryCatch &tryCatch, bool showLine) +{ + HandleScope scope(isolate); + Local context = isolate->GetCurrentContext(); + Local message = tryCatch.Message(); + + if (showLine && !message.IsEmpty()) { + String::Utf8Value filename(isolate, message->GetScriptResourceName()); + String::Utf8Value msg(isolate, message->Get()); + Maybe linenum = message->GetLineNumber(context); + LOGE(EXC_TAG, "Exception occurred at %s:%i: %s", *filename, linenum.FromMaybe(-1), *msg); + } + + // Log the stack trace if we have one + MaybeLocal maybeStackTrace = tryCatch.StackTrace(context); + if (!maybeStackTrace.IsEmpty()) { + Local stack = maybeStackTrace.ToLocalChecked(); + String::Utf8Value trace(isolate, stack); + if (trace.length() > 0 && !stack->IsUndefined()) { + LOGD(EXC_TAG, *trace); + return; + } + } + + // no/empty stack trace, so if the exception is an object, + // try to get the 'message' and 'name' properties + Local exception = tryCatch.Exception(); + if (exception->IsObject()) { + Local exceptionObj = exception.As(); + MaybeLocal message = exceptionObj->Get(context, NEW_SYMBOL(isolate, "message")); + MaybeLocal name = exceptionObj->Get(context, NEW_SYMBOL(isolate, "name")); + + if (!message.IsEmpty() && !message.ToLocalChecked()->IsUndefined() && !name.IsEmpty() && !name.ToLocalChecked()->IsUndefined()) { + String::Utf8Value nameValue(isolate, name.ToLocalChecked()); + String::Utf8Value messageValue(isolate, message.ToLocalChecked()); + LOGE(EXC_TAG, "%s: %s", *nameValue, *messageValue); + return; + } + } + + // Fall back to logging exception as a string + String::Utf8Value error(isolate, exception); + LOGE(EXC_TAG, *error); +} + + void V8Util::openJSErrorDialog(Isolate* isolate, TryCatch &tryCatch) { JNIEnv *env = JNIUtil::getJNIEnv(); @@ -221,6 +267,10 @@ void V8Util::openJSErrorDialog(Isolate* isolate, TryCatch &tryCatch) static int uncaughtExceptionCounter = 0; +/** + TODO TOCK: As long as I see this counter is NEVER increased NOWadays! +*/ + void V8Util::fatalException(Isolate* isolate, TryCatch &tryCatch) { HandleScope scope(isolate); From 07a381ece84da49cd6581b66fc2033ed008f1c75 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Sun, 9 Feb 2025 15:57:33 +0100 Subject: [PATCH 07/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 43 +++++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index d5fbe1888b0..97f4a341ec4 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -177,8 +177,8 @@ static void logV8Exception(Local msg, Local data) } // namespace titanium static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { -// V8Util::openJSErrorDialog(V8Runtime::v8_isolate, tryCatch); -// V8Util::reportException(V8Runtime::v8_isolate, tryCatch, true); + + // Extract main Objects v8::Isolate* isolate = data.GetIsolate(); v8::Local _promise = data.GetPromise(); @@ -186,6 +186,8 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { v8::PromiseRejectEvent e = data.GetEvent(); Local context = isolate->GetCurrentContext(); // V8Runtime::v8_isolate ? + // Extract Error message + v8::Local message = v8::Exception::CreateMessage(isolate, value); v8::String::Utf8Value utf8Message(isolate, message->Get()); v8::String::Utf8Value utf8ScriptName(isolate, message->GetScriptResourceName()); @@ -201,6 +203,8 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { LOGE(TAG, "%s", *utf8ScriptName); */ + + // Log Error message to Console LOGE(TAG, "%s", *utf8Message); LOGE(TAG, "%s @ %d >>> %s", @@ -217,8 +221,39 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { } } -// V8::TryCatch tryCatch(isolate); -// titanium::V8Util::fatalException(isolate, tryCatch); + // Report Exception to JS via krollRuntimeDispatchExceptionMethod + // Now without StackTrace ( available for Promises? ) + + JNIEnv* env = JNIUtil::getJNIEnv(); + if (!env) { + return; + } + jstring title = env->NewStringUTF("Rejected Promises"); + jstring errorMessage = TypeConverter::jsValueToJavaString(isolate, env, message->Get()); + jstring resourceName = TypeConverter::jsValueToJavaString(isolate, env, message->GetScriptResourceName()); +// jstring sourceLine = TypeConverter::jsValueToJavaString(isolate, env, message->GetSourceLine(context).FromMaybe(Null(isolate).As())); +// jstring jsStackString = TypeConverter::jsValueToJavaString(isolate, env, jsStack); +// jstring javaStackString = TypeConverter::jsValueToJavaString(isolate, env, javaStack); + env->CallStaticVoidMethod( + JNIUtil::krollRuntimeClass, + JNIUtil::krollRuntimeDispatchExceptionMethod, + title, + errorMessage, + resourceName, + title /* null */ /*message->GetLineNumber(context).FromMaybe(-1)*/ , + title /* null */ /*sourceLine*/, + title /* null */ /*message->GetEndColumn(context).FromMaybe(-1)*/, + title /* null */ /*jsStackString*/, + title /* null */ /*javaStackString*/; + env->DeleteLocalRef(title); + env->DeleteLocalRef(errorMessage); + env->DeleteLocalRef(resourceName); + /* + env->DeleteLocalRef(sourceLine); + env->DeleteLocalRef(jsStackString); + env->DeleteLocalRef(javaStackString); + */ + } extern "C" { From e61cbd83e1a7a4e7b2009c9d989531b323b922b3 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Sun, 9 Feb 2025 16:05:31 +0100 Subject: [PATCH 08/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index 97f4a341ec4..c48d3003af8 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -240,9 +240,9 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { title, errorMessage, resourceName, - title /* null */ /*message->GetLineNumber(context).FromMaybe(-1)*/ , + -1 /* null */ /*message->GetLineNumber(context).FromMaybe(-1)*/ , title /* null */ /*sourceLine*/, - title /* null */ /*message->GetEndColumn(context).FromMaybe(-1)*/, + -1 /* null */ /*message->GetEndColumn(context).FromMaybe(-1)*/, title /* null */ /*jsStackString*/, title /* null */ /*javaStackString*/; env->DeleteLocalRef(title); From 3ce8d0a3a5c63620174e7a7e81d85dd39fe22aa0 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 00:36:42 +0100 Subject: [PATCH 09/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index c48d3003af8..ac95c0dcd5c 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -180,10 +180,10 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { // Extract main Objects - v8::Isolate* isolate = data.GetIsolate(); - v8::Local _promise = data.GetPromise(); + v8::Local promise = data.GetPromise(); + v8::Isolate* isolate = promise->GetIsolate(); v8::Local value = data.GetValue(); - v8::PromiseRejectEvent e = data.GetEvent(); + v8::PromiseRejectEvent event = data.GetEvent(); Local context = isolate->GetCurrentContext(); // V8Runtime::v8_isolate ? // Extract Error message @@ -217,26 +217,26 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { v8::String::Utf8Value error(isolate, value); LOGE("Unhandled Promise Rejection: %s", *error); } else { - LOGE("Unhandled Promise Rejection with no message",); + LOGE("Unhandled Promise Rejection with no message"); } } // Report Exception to JS via krollRuntimeDispatchExceptionMethod // Now without StackTrace ( available for Promises? ) - JNIEnv* env = JNIUtil::getJNIEnv(); + titanium::JNIEnv* env = JNIUtil::getJNIEnv(); if (!env) { return; } jstring title = env->NewStringUTF("Rejected Promises"); - jstring errorMessage = TypeConverter::jsValueToJavaString(isolate, env, message->Get()); - jstring resourceName = TypeConverter::jsValueToJavaString(isolate, env, message->GetScriptResourceName()); -// jstring sourceLine = TypeConverter::jsValueToJavaString(isolate, env, message->GetSourceLine(context).FromMaybe(Null(isolate).As())); -// jstring jsStackString = TypeConverter::jsValueToJavaString(isolate, env, jsStack); -// jstring javaStackString = TypeConverter::jsValueToJavaString(isolate, env, javaStack); + jstring errorMessage = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->Get()); + jstring resourceName = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->GetScriptResourceName()); +// jstring sourceLine = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->GetSourceLine(context).FromMaybe(Null(isolate).As())); +// jstring jsStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, jsStack); +// jstring javaStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, javaStack); env->CallStaticVoidMethod( - JNIUtil::krollRuntimeClass, - JNIUtil::krollRuntimeDispatchExceptionMethod, + titanium::JNIUtil::krollRuntimeClass, + titanium::JNIUtil::krollRuntimeDispatchExceptionMethod, title, errorMessage, resourceName, @@ -244,7 +244,7 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { title /* null */ /*sourceLine*/, -1 /* null */ /*message->GetEndColumn(context).FromMaybe(-1)*/, title /* null */ /*jsStackString*/, - title /* null */ /*javaStackString*/; + title /* null */ /*javaStackString*/); env->DeleteLocalRef(title); env->DeleteLocalRef(errorMessage); env->DeleteLocalRef(resourceName); From 5db21dd1f972b5c11976a730936908882c741786 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 00:50:13 +0100 Subject: [PATCH 10/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index ac95c0dcd5c..df935e3d08c 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -225,6 +225,10 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { // Now without StackTrace ( available for Promises? ) titanium::JNIEnv* env = JNIUtil::getJNIEnv(); + + // TODO TOCK : Alternative + // titanium::JNIEnv* env = JNIScope::getEnv(); + if (!env) { return; } @@ -240,9 +244,9 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { title, errorMessage, resourceName, - -1 /* null */ /*message->GetLineNumber(context).FromMaybe(-1)*/ , + title /* null */ /*message->GetLineNumber(context).FromMaybe(-1)*/ , title /* null */ /*sourceLine*/, - -1 /* null */ /*message->GetEndColumn(context).FromMaybe(-1)*/, + title /* null */ /*message->GetEndColumn(context).FromMaybe(-1)*/, title /* null */ /*jsStackString*/, title /* null */ /*javaStackString*/); env->DeleteLocalRef(title); From 90ef049849e91557f0e4df59d512bf68a087cb7d Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 00:56:04 +0100 Subject: [PATCH 11/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index df935e3d08c..41632317989 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -244,11 +244,11 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { title, errorMessage, resourceName, - title /* null */ /*message->GetLineNumber(context).FromMaybe(-1)*/ , - title /* null */ /*sourceLine*/, - title /* null */ /*message->GetEndColumn(context).FromMaybe(-1)*/, - title /* null */ /*jsStackString*/, - title /* null */ /*javaStackString*/); + title /*message->GetLineNumber(context).FromMaybe(-1)*/ , + title /*sourceLine*/, + title /*message->GetEndColumn(context).FromMaybe(-1)*/, + title /*jsStackString*/, + title /*javaStackString*/); env->DeleteLocalRef(title); env->DeleteLocalRef(errorMessage); env->DeleteLocalRef(resourceName); From f4f706983e7552659bad445b2dac3d27777e61ff Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 10:23:14 +0100 Subject: [PATCH 12/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index 41632317989..0f706580492 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -224,7 +224,7 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { // Report Exception to JS via krollRuntimeDispatchExceptionMethod // Now without StackTrace ( available for Promises? ) - titanium::JNIEnv* env = JNIUtil::getJNIEnv(); + titanium::JNIEnv* env = titanium::JNIUtil::getJNIEnv(); // TODO TOCK : Alternative // titanium::JNIEnv* env = JNIScope::getEnv(); From 5495fc990376e62e8a8f4b05194b2f87b7192594 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 16:39:23 +0100 Subject: [PATCH 13/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index 0f706580492..d88b1c03334 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -224,7 +224,7 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { // Report Exception to JS via krollRuntimeDispatchExceptionMethod // Now without StackTrace ( available for Promises? ) - titanium::JNIEnv* env = titanium::JNIUtil::getJNIEnv(); + JNIEnv* env = titanium::JNIUtil::getJNIEnv(); // TODO TOCK : Alternative // titanium::JNIEnv* env = JNIScope::getEnv(); From 25606c37feeb0ff7af3e56e5d6ccf1ee4c349b4e Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 16:42:06 +0100 Subject: [PATCH 14/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index d88b1c03334..66b2f883359 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -212,6 +212,7 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { message->GetLineNumber(context).FromMaybe(-1), *utf8SourceLine); +/* if (event == v8::kPromiseRejectWithNoHandler) { if (!value.IsEmpty()) { v8::String::Utf8Value error(isolate, value); @@ -220,6 +221,7 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { LOGE("Unhandled Promise Rejection with no message"); } } +*/ // Report Exception to JS via krollRuntimeDispatchExceptionMethod // Now without StackTrace ( available for Promises? ) From c9f7ebdcb2a64eac69dadaafd4f4a8020fc97e94 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 16:59:30 +0100 Subject: [PATCH 15/24] Update V8Runtime.cpp --- android/runtime/v8/src/native/V8Runtime.cpp | 88 +-------------------- 1 file changed, 1 insertion(+), 87 deletions(-) diff --git a/android/runtime/v8/src/native/V8Runtime.cpp b/android/runtime/v8/src/native/V8Runtime.cpp index 66b2f883359..cafcba0268a 100644 --- a/android/runtime/v8/src/native/V8Runtime.cpp +++ b/android/runtime/v8/src/native/V8Runtime.cpp @@ -176,92 +176,6 @@ static void logV8Exception(Local msg, Local data) } // namespace titanium -static void _PromiseRejectCallback(v8::PromiseRejectMessage data) { - - // Extract main Objects - - v8::Local promise = data.GetPromise(); - v8::Isolate* isolate = promise->GetIsolate(); - v8::Local value = data.GetValue(); - v8::PromiseRejectEvent event = data.GetEvent(); - Local context = isolate->GetCurrentContext(); // V8Runtime::v8_isolate ? - - // Extract Error message - - v8::Local message = v8::Exception::CreateMessage(isolate, value); - v8::String::Utf8Value utf8Message(isolate, message->Get()); - v8::String::Utf8Value utf8ScriptName(isolate, message->GetScriptResourceName()); - v8::Local sourceLine = message->GetSourceLine(context).ToLocalChecked(); - v8::String::Utf8Value utf8SourceLine(isolate, sourceLine); - -/* - // Alternative version: - - String::Utf8Value utf8Message(V8Runtime::v8_isolate, data->Get()); - String::Utf8Value utf8ScriptName(V8Runtime::v8_isolate, data->GetScriptResourceName()); - LOGE(TAG, *utf8Message); - LOGE(TAG, "%s", *utf8ScriptName); - -*/ - - // Log Error message to Console - - LOGE(TAG, "%s", *utf8Message); - LOGE(TAG, "%s @ %d >>> %s", - *utf8ScriptName, - message->GetLineNumber(context).FromMaybe(-1), - *utf8SourceLine); - -/* - if (event == v8::kPromiseRejectWithNoHandler) { - if (!value.IsEmpty()) { - v8::String::Utf8Value error(isolate, value); - LOGE("Unhandled Promise Rejection: %s", *error); - } else { - LOGE("Unhandled Promise Rejection with no message"); - } - } -*/ - - // Report Exception to JS via krollRuntimeDispatchExceptionMethod - // Now without StackTrace ( available for Promises? ) - - JNIEnv* env = titanium::JNIUtil::getJNIEnv(); - - // TODO TOCK : Alternative - // titanium::JNIEnv* env = JNIScope::getEnv(); - - if (!env) { - return; - } - jstring title = env->NewStringUTF("Rejected Promises"); - jstring errorMessage = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->Get()); - jstring resourceName = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->GetScriptResourceName()); -// jstring sourceLine = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->GetSourceLine(context).FromMaybe(Null(isolate).As())); -// jstring jsStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, jsStack); -// jstring javaStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, javaStack); - env->CallStaticVoidMethod( - titanium::JNIUtil::krollRuntimeClass, - titanium::JNIUtil::krollRuntimeDispatchExceptionMethod, - title, - errorMessage, - resourceName, - title /*message->GetLineNumber(context).FromMaybe(-1)*/ , - title /*sourceLine*/, - title /*message->GetEndColumn(context).FromMaybe(-1)*/, - title /*jsStackString*/, - title /*javaStackString*/); - env->DeleteLocalRef(title); - env->DeleteLocalRef(errorMessage); - env->DeleteLocalRef(resourceName); - /* - env->DeleteLocalRef(sourceLine); - env->DeleteLocalRef(jsStackString); - env->DeleteLocalRef(javaStackString); - */ - -} - extern "C" { using namespace titanium; @@ -309,7 +223,7 @@ JNIEXPORT void JNICALL Java_org_appcelerator_kroll_runtime_v8_V8Runtime_nativeIn // isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException); // isolate->SetAutorunMicrotasks(false); // isolate->SetFatalErrorHandler(OnFatalError); - isolate->SetPromiseRejectCallback(_PromiseRejectCallback); + isolate->SetPromiseRejectCallback(V8Util::reportRejection); isolate->SetCaptureStackTraceForUncaughtExceptions(true, 10, v8::StackTrace::kOverview); } else { isolate = V8Runtime::v8_isolate; From 8992417d2e8128bdcbd0803ec154a9b2d409452f Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:00:52 +0100 Subject: [PATCH 16/24] Update V8Util.cpp --- android/runtime/v8/src/native/V8Util.cpp | 92 +++++++++++++----------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/android/runtime/v8/src/native/V8Util.cpp b/android/runtime/v8/src/native/V8Util.cpp index 0deca30a7fb..4fd72689db4 100644 --- a/android/runtime/v8/src/native/V8Util.cpp +++ b/android/runtime/v8/src/native/V8Util.cpp @@ -157,52 +157,58 @@ void V8Util::reportException(Isolate* isolate, TryCatch &tryCatch, bool showLine LOGE(EXC_TAG, *error); } -void V8Util::reportRejection(Isolate* isolate, TryCatch &tryCatch, bool showLine) +void V8Util::reportRejection(v8::PromiseRejectMessage data) { - HandleScope scope(isolate); - Local context = isolate->GetCurrentContext(); - Local message = tryCatch.Message(); - - if (showLine && !message.IsEmpty()) { - String::Utf8Value filename(isolate, message->GetScriptResourceName()); - String::Utf8Value msg(isolate, message->Get()); - Maybe linenum = message->GetLineNumber(context); - LOGE(EXC_TAG, "Exception occurred at %s:%i: %s", *filename, linenum.FromMaybe(-1), *msg); - } - - // Log the stack trace if we have one - MaybeLocal maybeStackTrace = tryCatch.StackTrace(context); - if (!maybeStackTrace.IsEmpty()) { - Local stack = maybeStackTrace.ToLocalChecked(); - String::Utf8Value trace(isolate, stack); - if (trace.length() > 0 && !stack->IsUndefined()) { - LOGD(EXC_TAG, *trace); - return; - } - } - - // no/empty stack trace, so if the exception is an object, - // try to get the 'message' and 'name' properties - Local exception = tryCatch.Exception(); - if (exception->IsObject()) { - Local exceptionObj = exception.As(); - MaybeLocal message = exceptionObj->Get(context, NEW_SYMBOL(isolate, "message")); - MaybeLocal name = exceptionObj->Get(context, NEW_SYMBOL(isolate, "name")); - - if (!message.IsEmpty() && !message.ToLocalChecked()->IsUndefined() && !name.IsEmpty() && !name.ToLocalChecked()->IsUndefined()) { - String::Utf8Value nameValue(isolate, name.ToLocalChecked()); - String::Utf8Value messageValue(isolate, message.ToLocalChecked()); - LOGE(EXC_TAG, "%s: %s", *nameValue, *messageValue); - return; - } - } - - // Fall back to logging exception as a string - String::Utf8Value error(isolate, exception); - LOGE(EXC_TAG, *error); + // Extract main Objects + v8::Local promise = data.GetPromise(); + v8::Isolate* isolate = promise->GetIsolate(); + v8::Local value = data.GetValue(); + v8::PromiseRejectEvent event = data.GetEvent(); + Local context = isolate->GetCurrentContext(); // V8Runtime::v8_isolate ? + // Extract Error message + v8::Local message = v8::Exception::CreateMessage(isolate, value); + v8::String::Utf8Value utf8Message(isolate, message->Get()); + v8::String::Utf8Value utf8ScriptName(isolate, message->GetScriptResourceName()); + v8::Local sourceLine = message->GetSourceLine(context).ToLocalChecked(); + v8::String::Utf8Value utf8SourceLine(isolate, sourceLine); + // Log Error message to Console + LOGE(TAG, "%s", *utf8Message); + LOGE(TAG, "%s @ %d >>> %s", + *utf8ScriptName, + message->GetLineNumber(context).FromMaybe(-1), + *utf8SourceLine); + + // Report Exception to JS via krollRuntimeDispatchExceptionMethod + // Now without StackTrace ( available for Promises? ) + + JNIEnv* env = titanium::JNIUtil::getJNIEnv(); + jstring title = env->NewStringUTF("Rejected Promises"); + jstring errorMessage = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->Get()); + jstring resourceName = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->GetScriptResourceName()); +// jstring sourceLine = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->GetSourceLine(context).FromMaybe(Null(isolate).As())); +// jstring jsStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, jsStack); +// jstring javaStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, javaStack); + env->CallStaticVoidMethod( + titanium::JNIUtil::krollRuntimeClass, + titanium::JNIUtil::krollRuntimeDispatchExceptionMethod, + title, + errorMessage, + resourceName, + title /*message->GetLineNumber(context).FromMaybe(-1)*/ , + title /*sourceLine*/, + title /*message->GetEndColumn(context).FromMaybe(-1)*/, + title /*jsStackString*/, + title /*javaStackString*/); + env->DeleteLocalRef(title); + env->DeleteLocalRef(errorMessage); + env->DeleteLocalRef(resourceName); + /* + env->DeleteLocalRef(sourceLine); + env->DeleteLocalRef(jsStackString); + env->DeleteLocalRef(javaStackString); + */ } - void V8Util::openJSErrorDialog(Isolate* isolate, TryCatch &tryCatch) { JNIEnv *env = JNIUtil::getJNIEnv(); From 26c8be84e2da57fdfb1a31ce1bbd15e9c157137d Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:07:37 +0100 Subject: [PATCH 17/24] Update V8Util.h --- android/runtime/v8/src/native/V8Util.h | 1 + 1 file changed, 1 insertion(+) diff --git a/android/runtime/v8/src/native/V8Util.h b/android/runtime/v8/src/native/V8Util.h index a9623323e7e..0f1fc34bb43 100644 --- a/android/runtime/v8/src/native/V8Util.h +++ b/android/runtime/v8/src/native/V8Util.h @@ -161,6 +161,7 @@ class V8Util { static void objectExtend(v8::Local dest, v8::Local src); // TODO: Remove when we do a breaking change! static void objectExtend(v8::Isolate* isolate, v8::Local dest, v8::Local src); static void reportException(v8::Isolate* isolate, v8::TryCatch &tryCatch, bool showLine = true); + static void reportRejection(v8::PromiseRejectMessage data); static void openJSErrorDialog(v8::Isolate* isolate, v8::TryCatch &tryCatch); static void fatalException(v8::Isolate* isolate, v8::TryCatch &tryCatch); static v8::Local jsonStringify(v8::Isolate* isolate, v8::Local value); From ed77266e76c8c1269b6fc59da6b84738133d3c45 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:45:00 +0100 Subject: [PATCH 18/24] Update V8Util.cpp --- android/runtime/v8/src/native/V8Util.cpp | 53 +++++++++++++++++------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/android/runtime/v8/src/native/V8Util.cpp b/android/runtime/v8/src/native/V8Util.cpp index 4fd72689db4..9ea94946f6d 100644 --- a/android/runtime/v8/src/native/V8Util.cpp +++ b/android/runtime/v8/src/native/V8Util.cpp @@ -165,12 +165,13 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) v8::Local value = data.GetValue(); v8::PromiseRejectEvent event = data.GetEvent(); Local context = isolate->GetCurrentContext(); // V8Runtime::v8_isolate ? - // Extract Error message + + // Extract Error message v8::Local message = v8::Exception::CreateMessage(isolate, value); v8::String::Utf8Value utf8Message(isolate, message->Get()); v8::String::Utf8Value utf8ScriptName(isolate, message->GetScriptResourceName()); - v8::Local sourceLine = message->GetSourceLine(context).ToLocalChecked(); - v8::String::Utf8Value utf8SourceLine(isolate, sourceLine); + v8::Local logSourceLine = message->GetSourceLine(context).ToLocalChecked(); + v8::String::Utf8Value utf8SourceLine(isolate, logSourceLine); // Log Error message to Console LOGE(TAG, "%s", *utf8Message); LOGE(TAG, "%s @ %d >>> %s", @@ -178,35 +179,57 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) message->GetLineNumber(context).FromMaybe(-1), *utf8SourceLine); + // Obtain javascript and java stack traces + + Local jsStack; + Local javaStack; + + if (value->IsObject()) { + Local error = value.As(); + jsStack = error->Get(context, STRING_NEW(isolate, "stack")).FromMaybe(Undefined(isolate).As()); + javaStack = error->Get(context, STRING_NEW(isolate, "nativeStack")).FromMaybe(Undefined(isolate).As()); + } + + // javascript stack trace not provided? obtain current javascript stack trace + if (jsStack.IsEmpty() || jsStack->IsNullOrUndefined()) { + Local frames = message->GetStackTrace(); + if (frames.IsEmpty() || !frames->GetFrameCount()) { + frames = StackTrace::CurrentStackTrace(isolate, MAX_STACK); + } + if (!frames.IsEmpty()) { + std::string stackString = V8Util::stackTraceString(isolate, frames); + if (!stackString.empty()) { + jsStack = String::NewFromUtf8(isolate, stackString.c_str(), v8::NewStringType::kNormal).ToLocalChecked().As(); + } + } + } + // Report Exception to JS via krollRuntimeDispatchExceptionMethod - // Now without StackTrace ( available for Promises? ) JNIEnv* env = titanium::JNIUtil::getJNIEnv(); - jstring title = env->NewStringUTF("Rejected Promises"); + jstring title = env->NewStringUTF("Rejected Promise"); jstring errorMessage = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->Get()); jstring resourceName = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->GetScriptResourceName()); -// jstring sourceLine = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->GetSourceLine(context).FromMaybe(Null(isolate).As())); -// jstring jsStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, jsStack); -// jstring javaStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, javaStack); + jstring sourceLine = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->GetSourceLine(context).FromMaybe(Null(isolate).As())); + jstring jsStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, jsStack); + jstring javaStackString = titanium::TypeConverter::jsValueToJavaString(isolate, env, javaStack); env->CallStaticVoidMethod( titanium::JNIUtil::krollRuntimeClass, titanium::JNIUtil::krollRuntimeDispatchExceptionMethod, title, errorMessage, resourceName, - title /*message->GetLineNumber(context).FromMaybe(-1)*/ , - title /*sourceLine*/, - title /*message->GetEndColumn(context).FromMaybe(-1)*/, - title /*jsStackString*/, - title /*javaStackString*/); + message->GetLineNumber(context).FromMaybe(-1), + sourceLine, + message->GetEndColumn(context).FromMaybe(-1), + jsStackString, + javaStackString); env->DeleteLocalRef(title); env->DeleteLocalRef(errorMessage); env->DeleteLocalRef(resourceName); - /* env->DeleteLocalRef(sourceLine); env->DeleteLocalRef(jsStackString); env->DeleteLocalRef(javaStackString); - */ } void V8Util::openJSErrorDialog(Isolate* isolate, TryCatch &tryCatch) From 8ce62288da857b434d302148e0f28904fafa15cd Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:31:54 +0100 Subject: [PATCH 19/24] Update V8Util.cpp --- android/runtime/v8/src/native/V8Util.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/android/runtime/v8/src/native/V8Util.cpp b/android/runtime/v8/src/native/V8Util.cpp index 9ea94946f6d..05418c09462 100644 --- a/android/runtime/v8/src/native/V8Util.cpp +++ b/android/runtime/v8/src/native/V8Util.cpp @@ -165,19 +165,19 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) v8::Local value = data.GetValue(); v8::PromiseRejectEvent event = data.GetEvent(); Local context = isolate->GetCurrentContext(); // V8Runtime::v8_isolate ? - + // Extract Error message v8::Local message = v8::Exception::CreateMessage(isolate, value); v8::String::Utf8Value utf8Message(isolate, message->Get()); v8::String::Utf8Value utf8ScriptName(isolate, message->GetScriptResourceName()); v8::Local logSourceLine = message->GetSourceLine(context).ToLocalChecked(); - v8::String::Utf8Value utf8SourceLine(isolate, logSourceLine); + v8::String::Utf8Value utf8SourceLine(isolate, logSourceLine); // Log Error message to Console LOGE(TAG, "%s", *utf8Message); - LOGE(TAG, "%s @ %d >>> %s", - *utf8ScriptName, - message->GetLineNumber(context).FromMaybe(-1), - *utf8SourceLine); + LOGE(TAG, "%s @ %d >>> %s", + *utf8ScriptName, + message->GetLineNumber(context).FromMaybe(-1), + *utf8SourceLine); // Obtain javascript and java stack traces @@ -227,7 +227,7 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) env->DeleteLocalRef(title); env->DeleteLocalRef(errorMessage); env->DeleteLocalRef(resourceName); - env->DeleteLocalRef(sourceLine); + env->DeleteLocalRef(sourceLine); env->DeleteLocalRef(jsStackString); env->DeleteLocalRef(javaStackString); } From 76474365e84a5832a466d77d1b335cadecaebb75 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:18:51 +0100 Subject: [PATCH 20/24] Update V8Util.cpp --- android/runtime/v8/src/native/V8Util.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/android/runtime/v8/src/native/V8Util.cpp b/android/runtime/v8/src/native/V8Util.cpp index 05418c09462..634a2d74f5e 100644 --- a/android/runtime/v8/src/native/V8Util.cpp +++ b/android/runtime/v8/src/native/V8Util.cpp @@ -296,10 +296,6 @@ void V8Util::openJSErrorDialog(Isolate* isolate, TryCatch &tryCatch) static int uncaughtExceptionCounter = 0; -/** - TODO TOCK: As long as I see this counter is NEVER increased NOWadays! -*/ - void V8Util::fatalException(Isolate* isolate, TryCatch &tryCatch) { HandleScope scope(isolate); From 2dc4982fe420389f22b4182b192c1b76acf18778 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Fri, 9 Jan 2026 22:04:32 +0100 Subject: [PATCH 21/24] Optimize V8Util.cpp --- android/runtime/v8/src/native/V8Util.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/android/runtime/v8/src/native/V8Util.cpp b/android/runtime/v8/src/native/V8Util.cpp index 105288c70e9..80ecbe0b03d 100644 --- a/android/runtime/v8/src/native/V8Util.cpp +++ b/android/runtime/v8/src/native/V8Util.cpp @@ -163,9 +163,8 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) v8::Local promise = data.GetPromise(); v8::Isolate* isolate = promise->GetIsolate(); v8::Local value = data.GetValue(); - v8::PromiseRejectEvent event = data.GetEvent(); - Local context = isolate->GetCurrentContext(); // V8Runtime::v8_isolate ? - + Local context = isolate->GetCurrentContext(); + // Extract Error message v8::Local message = v8::Exception::CreateMessage(isolate, value); v8::String::Utf8Value utf8Message(isolate, message->Get()); From 9c6fcf1e50bd56d9f140ecbea262cf55a49a1725 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Sun, 8 Feb 2026 23:19:04 +0100 Subject: [PATCH 22/24] Update V8Util.cpp V8 Retrown Rejection (HandlerAddedAfterReject) safely discarded. --- android/runtime/v8/src/native/V8Util.cpp | 30 +++++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/android/runtime/v8/src/native/V8Util.cpp b/android/runtime/v8/src/native/V8Util.cpp index 80ecbe0b03d..510631d987f 100644 --- a/android/runtime/v8/src/native/V8Util.cpp +++ b/android/runtime/v8/src/native/V8Util.cpp @@ -159,12 +159,30 @@ void V8Util::reportException(Isolate* isolate, TryCatch &tryCatch, bool showLine void V8Util::reportRejection(v8::PromiseRejectMessage data) { + // Rejection consistency check + v8::PromiseRejectEvent event=data.GetEvent(); + if (event != v8::kPromiseRejectWithNoHandler) { + // Avoid invalid 2° dispatch for async ReferenceError (Handler Added After Reject) + LOGE(TAG, "Invalid PromiseRejectEvent Discarded (Invalid Event)"); + if (event == v8::kPromiseHandlerAddedAfterReject) + LOGE(TAG, "PromiseRejectEvent Handler Added After Reject"); + else + LOGE(TAG, "PromiseRejectEvent Unexpected Event (%d)",event); + return; + } + // Extract main Objects - v8::Local promise = data.GetPromise(); - v8::Isolate* isolate = promise->GetIsolate(); - v8::Local value = data.GetValue(); + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::HandleScope handle_scope(isolate); Local context = isolate->GetCurrentContext(); - + v8::Local value = data.GetValue(); + + // Value consistency check + if (value.IsEmpty()) { + LOGE(TAG, "Invalid PromiseRejectEvent Discarded (Empty Value)"); + return; + } + // Extract Error message v8::Local message = v8::Exception::CreateMessage(isolate, value); v8::String::Utf8Value utf8Message(isolate, message->Get()); @@ -180,8 +198,8 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) // Obtain javascript and java stack traces - Local jsStack; - Local javaStack; + Local jsStack=Undefined(isolate); + Local javaStack=Undefined(isolate); if (value->IsObject()) { Local error = value.As(); From fcc2900d695acb52f74db3adb60a6117da6f0c04 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 9 Feb 2026 16:48:35 +0100 Subject: [PATCH 23/24] Update V8Util.cpp Unhandled Rejection Error Deduplication on async unwind function call stack. --- android/runtime/v8/src/native/V8Util.cpp | 62 ++++++++++++++++-------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/android/runtime/v8/src/native/V8Util.cpp b/android/runtime/v8/src/native/V8Util.cpp index 510631d987f..e8fbe8f264e 100644 --- a/android/runtime/v8/src/native/V8Util.cpp +++ b/android/runtime/v8/src/native/V8Util.cpp @@ -6,6 +6,7 @@ */ #include #include +#include #include "V8Util.h" #include "JNIUtil.h" @@ -157,38 +158,60 @@ void V8Util::reportException(Isolate* isolate, TryCatch &tryCatch, bool showLine LOGE(EXC_TAG, *error); } +static thread_local std::unordered_set*> seenErrors; +static void errorWeakCallback(const v8::WeakCallbackInfo>& info) { + v8::Global* g = info.GetParameter(); + seenErrors.erase(g); + g->Reset(); + delete g; +} void V8Util::reportRejection(v8::PromiseRejectMessage data) { - // Rejection consistency check - v8::PromiseRejectEvent event=data.GetEvent(); - if (event != v8::kPromiseRejectWithNoHandler) { - // Avoid invalid 2° dispatch for async ReferenceError (Handler Added After Reject) - LOGE(TAG, "Invalid PromiseRejectEvent Discarded (Invalid Event)"); - if (event == v8::kPromiseHandlerAddedAfterReject) - LOGE(TAG, "PromiseRejectEvent Handler Added After Reject"); - else - LOGE(TAG, "PromiseRejectEvent Unexpected Event (%d)",event); - return; - } - // Extract main Objects v8::Isolate* isolate = v8::Isolate::GetCurrent(); - v8::HandleScope handle_scope(isolate); - Local context = isolate->GetCurrentContext(); - v8::Local value = data.GetValue(); - + v8::HandleScope handle_scope(isolate); + v8::Local context = isolate->GetCurrentContext(); + v8::Local value=data.GetValue(); + + // Deduplication Process and Rejection consistency check + v8::Local promise = data.GetPromise(); + int id = promise->GetIdentityHash(); + v8::PromiseRejectEvent event = data.GetEvent(); + if (event == v8::kPromiseRejectWithNoHandler) { + + // Deduplicate on same value (Error) + for (v8::Global* g : seenErrors) { + if (g->Get(isolate)->StrictEquals(value)) { + LOGE(TAG, "PromiseRejectEvent duplicated discarded"); // LOGD + return; + } + } + } else if (event == v8::kPromiseHandlerAddedAfterReject) { + LOGE(TAG, "PromiseRejectEvent handler added after reject discarded"); // LOGD + return; + } else { + LOGE(TAG, "PromiseRejectEvent with unexpected event (%d) Lost", event); + return; + } + // Value consistency check if (value.IsEmpty()) { - LOGE(TAG, "Invalid PromiseRejectEvent Discarded (Empty Value)"); + LOGE(TAG, "PromiseRejectEvent with Empty Value Lost"); return; } + // Track the Error with Global + weak + v8::Global* g = new v8::Global(isolate, value); + g->SetWeak(g, errorWeakCallback, v8::WeakCallbackType::kParameter); + seenErrors.insert(g); + // Extract Error message v8::Local message = v8::Exception::CreateMessage(isolate, value); v8::String::Utf8Value utf8Message(isolate, message->Get()); v8::String::Utf8Value utf8ScriptName(isolate, message->GetScriptResourceName()); v8::Local logSourceLine = message->GetSourceLine(context).ToLocalChecked(); v8::String::Utf8Value utf8SourceLine(isolate, logSourceLine); + // Log Error message to Console LOGE(TAG, "%s", *utf8Message); LOGE(TAG, "%s @ %d >>> %s", @@ -197,10 +220,8 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) *utf8SourceLine); // Obtain javascript and java stack traces - Local jsStack=Undefined(isolate); Local javaStack=Undefined(isolate); - if (value->IsObject()) { Local error = value.As(); jsStack = error->Get(context, STRING_NEW(isolate, "stack")).FromMaybe(Undefined(isolate).As()); @@ -222,7 +243,6 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) } // Report Exception to JS via krollRuntimeDispatchExceptionMethod - JNIEnv* env = titanium::JNIUtil::getJNIEnv(); jstring title = env->NewStringUTF("Rejected Promise"); jstring errorMessage = titanium::TypeConverter::jsValueToJavaString(isolate, env, message->Get()); @@ -240,7 +260,7 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) sourceLine, message->GetEndColumn(context).FromMaybe(-1), jsStackString, - javaStackString); + javaStackString); env->DeleteLocalRef(title); env->DeleteLocalRef(errorMessage); env->DeleteLocalRef(resourceName); From 5e2730a3e38622a2dcb98515a586f1fb63098321 Mon Sep 17 00:00:00 2001 From: "Informate.it" <40699080+Informate@users.noreply.github.com> Date: Mon, 9 Feb 2026 16:58:19 +0100 Subject: [PATCH 24/24] Update V8Util.cpp Minor fixes --- android/runtime/v8/src/native/V8Util.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/android/runtime/v8/src/native/V8Util.cpp b/android/runtime/v8/src/native/V8Util.cpp index e8fbe8f264e..1ef4da82053 100644 --- a/android/runtime/v8/src/native/V8Util.cpp +++ b/android/runtime/v8/src/native/V8Util.cpp @@ -169,34 +169,32 @@ void V8Util::reportRejection(v8::PromiseRejectMessage data) { // Extract main Objects v8::Isolate* isolate = v8::Isolate::GetCurrent(); - v8::HandleScope handle_scope(isolate); - v8::Local context = isolate->GetCurrentContext(); + v8::HandleScope handle_scope(isolate); + v8::Local context = isolate->GetCurrentContext(); v8::Local value=data.GetValue(); // Deduplication Process and Rejection consistency check - v8::Local promise = data.GetPromise(); - int id = promise->GetIdentityHash(); v8::PromiseRejectEvent event = data.GetEvent(); if (event == v8::kPromiseRejectWithNoHandler) { - + // Deduplicate on same value (Error) for (v8::Global* g : seenErrors) { if (g->Get(isolate)->StrictEquals(value)) { - LOGE(TAG, "PromiseRejectEvent duplicated discarded"); // LOGD - return; + LOGD(EXC_TAG, "PromiseRejectEvent duplicated discarded"); + return; } } } else if (event == v8::kPromiseHandlerAddedAfterReject) { - LOGE(TAG, "PromiseRejectEvent handler added after reject discarded"); // LOGD + LOGD(EXC_TAG, "PromiseRejectEvent handler added after reject discarded"); return; } else { - LOGE(TAG, "PromiseRejectEvent with unexpected event (%d) Lost", event); + LOGE(EXC_TAG, "PromiseRejectEvent with unexpected event (%d) Lost", event); return; } - + // Value consistency check if (value.IsEmpty()) { - LOGE(TAG, "PromiseRejectEvent with Empty Value Lost"); + LOGE(EXC_TAG, "PromiseRejectEvent with Empty Value Lost"); return; }