diff --git a/libraries/script-engine/src/v8/ScriptEngineV8.cpp b/libraries/script-engine/src/v8/ScriptEngineV8.cpp index 3c7e3fb49f..a7d0cd8c8d 100644 --- a/libraries/script-engine/src/v8/ScriptEngineV8.cpp +++ b/libraries/script-engine/src/v8/ScriptEngineV8.cpp @@ -634,9 +634,13 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, v8::Local v8Result; if (!maybeResult.ToLocal(&v8Result)) { v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Exception()); - QString errorMessage = QString(*utf8Value); - qCWarning(scriptengine_v8) << __FUNCTION__ << "---------- hasCaught:" << errorMessage; - qCWarning(scriptengine_v8) << __FUNCTION__ << "---------- tryCatch details:" << formatErrorMessageFromTryCatch(tryCatch); + QString errorMessage = QString(__FUNCTION__) + " hasCaught:" + QString(*utf8Value) + "\n" + + "tryCatch details:" + formatErrorMessageFromTryCatch(tryCatch); + if (_manager) { + _manager->scriptErrorMessage(errorMessage); + } else { + qWarning(scriptengine_v8) << errorMessage; + } } if (hasUncaughtException()) { @@ -685,6 +689,12 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f { v8::TryCatch tryCatch(getIsolate()); if (!v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) { + QString errorMessage(QString("Error while compiling script: \"") + fileName + QString("\" ") + formatErrorMessageFromTryCatch(tryCatch)); + if (_manager) { + _manager->scriptErrorMessage(errorMessage); + } else { + qDebug(scriptengine_v8) << errorMessage; + } setUncaughtException(tryCatch, "Error while compiling script"); _evaluatingCounter--; return nullValue(); @@ -697,7 +707,12 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f Q_ASSERT(tryCatchRun.HasCaught()); auto runError = tryCatchRun.Message(); ScriptValue errorValue(new ScriptValueV8Wrapper(this, V8ScriptValue(this, runError->Get()))); - qCDebug(scriptengine_v8) << "Running script: \"" << fileName << "\" " << formatErrorMessageFromTryCatch(tryCatchRun); + QString errorMessage(QString("Running script: \"") + fileName + QString("\" ") + formatErrorMessageFromTryCatch(tryCatchRun)); + if (_manager) { + _manager->scriptErrorMessage(errorMessage); + } else { + qDebug(scriptengine_v8) << errorMessage; + } setUncaughtException(tryCatchRun, "script evaluation"); _evaluatingCounter--; @@ -749,7 +764,7 @@ void ScriptEngineV8::setUncaughtException(const v8::TryCatch &tryCatch, const QS if (backtraceV8String->IsString()) { if (v8::Local::Cast(backtraceV8String)->Length() > 0) { v8::String::Utf8Value backtraceUtf8Value(getIsolate(), backtraceV8String); - QString errorBacktrace = *backtraceUtf8Value; + QString errorBacktrace = QString(*backtraceUtf8Value).replace("\\n","\n"); ex->backtrace = errorBacktrace.split("\n"); } @@ -790,14 +805,14 @@ QString ScriptEngineV8::formatErrorMessageFromTryCatch(v8::TryCatch &tryCatch) { if (backtraceV8String->IsString()) { if (v8::Local::Cast(backtraceV8String)->Length() > 0) { v8::String::Utf8Value backtraceUtf8Value(getIsolate(), backtraceV8String); - errorBacktrace = *backtraceUtf8Value; + errorBacktrace = QString(*backtraceUtf8Value).replace("\\n","\n"); } } } QTextStream resultStream(&result); resultStream << "failed on line " << errorLineNumber << " column " << errorColumnNumber << " with message: \"" << errorMessage <<"\" backtrace: " << errorBacktrace; } - return result; + return result.replace("\\n", "\n"); } v8::Local ScriptEngineV8::getObjectProxyTemplate() { diff --git a/libraries/script-engine/src/v8/ScriptEngineV8.h b/libraries/script-engine/src/v8/ScriptEngineV8.h index 68907b14a8..6ffa539a86 100644 --- a/libraries/script-engine/src/v8/ScriptEngineV8.h +++ b/libraries/script-engine/src/v8/ScriptEngineV8.h @@ -272,6 +272,7 @@ private: std::atomic scriptValueCount{0}; std::atomic scriptValueProxyCount{0}; #endif + friend ScriptValueV8Wrapper; }; // This class is used to automatically add context to script engine's context list that is used by C++ calls diff --git a/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp b/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp index cd9cd46513..616e252d7c 100644 --- a/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp +++ b/libraries/script-engine/src/v8/ScriptObjectV8Proxy.cpp @@ -1255,9 +1255,14 @@ int ScriptSignalV8Proxy::qt_metacall(QMetaObject::Call call, int id, void** argu v8::TryCatch tryCatch(isolate); callback->Call(functionContext, v8This, numArgs, args); if (tryCatch.HasCaught()) { - qCDebug(scriptengine) << "Signal proxy " << fullName() << " connection call failed: \"" - << _engine->formatErrorMessageFromTryCatch(tryCatch) - << "\nThis provided: " << conn.thisValue.get()->IsObject(); + QString errorMessage(QString("Signal proxy ") + fullName() + " connection call failed: \"" + + _engine->formatErrorMessageFromTryCatch(tryCatch) + + "\nThis provided: " + QString::number(conn.thisValue.get()->IsObject())); + if (_engine->_manager) { + _engine->_manager->scriptErrorMessage(errorMessage); + } else { + qDebug(scriptengine_v8) << errorMessage; + } _engine->setUncaughtException(tryCatch, "Error in signal proxy"); } diff --git a/libraries/script-engine/src/v8/ScriptProgramV8Wrapper.cpp b/libraries/script-engine/src/v8/ScriptProgramV8Wrapper.cpp index 71a0874513..f304daf00a 100644 --- a/libraries/script-engine/src/v8/ScriptProgramV8Wrapper.cpp +++ b/libraries/script-engine/src/v8/ScriptProgramV8Wrapper.cpp @@ -69,7 +69,7 @@ bool ScriptProgramV8Wrapper::compile() { if (backtraceV8String->IsString()) { if (v8::Local::Cast(backtraceV8String)->Length() > 0) { v8::String::Utf8Value backtraceUtf8Value(isolate, backtraceV8String); - errorBacktrace = *backtraceUtf8Value; + errorBacktrace = QString(*backtraceUtf8Value).replace("\\n","\n"); } } } diff --git a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp index c4c172d218..fb2cf85a9f 100644 --- a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp +++ b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp @@ -102,15 +102,24 @@ ScriptValue ScriptValueV8Wrapper::call(const ScriptValue& thisObject, const Scri auto maybeResult = v8Function->Call(_engine->getContext(), recv, args.length(), v8Args); lock.unlock(); if (tryCatch.HasCaught()) { - qCDebug(scriptengine_v8) << "Function call failed: \"" << _engine->formatErrorMessageFromTryCatch(tryCatch); + QString errorMessage(QString("Function call failed: \"") + _engine->formatErrorMessageFromTryCatch(tryCatch)); + if (_engine->_manager) { + _engine->_manager->scriptErrorMessage(errorMessage); + } else { + qDebug(scriptengine_v8) << errorMessage; + } } v8::Local result; Q_ASSERT(_engine == _value.getEngine()); if (maybeResult.ToLocal(&result)) { return ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(_engine, result))); } else { - //V8TODO Add more details - qCWarning(scriptengine_v8) << "JS function call failed"; + QString errorMessage("JS function call failed: " + _engine->currentContext()->backtrace().join("\n")); + if (_engine->_manager) { + _engine->_manager->scriptErrorMessage(errorMessage); + } else { + qDebug(scriptengine_v8) << errorMessage; + } return _engine->undefinedValue(); } }