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<v8::Value> 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<v8::String>::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<v8::String>::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<v8::ObjectTemplate> 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<size_t> scriptValueCount{0};
     std::atomic<size_t> 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<v8::String>::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<v8::Value> 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();
     }
 }