* Get rid of maybeEmitUncaughtException * Mostly get rid of makeError * Introduce exception hierarchy, change exceptions to shared_ptr * Simplify exception throwing code
Showing the changes to libraries/script-engine/src/v8/ScriptEngineV8.cpp (1 of 10 files). Show all
Unified · Split
| @@ -71,20 +71,17 @@ bool ScriptEngineV8::IS_THREADSAFE_INVOCATION(const QThread* thread, const QStri · 70 unmodified lines | |||
| 71 | return false; | 71 | return false; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | // engine-aware JS Error copier and factory | 74 | ScriptValue ScriptEngineV8::makeError(const ScriptValue& _other, const QString& type) { |
| 75 | V8ScriptValue ScriptEngineV8::makeError(const V8ScriptValue& _other, const QString& type) { | ||
| 76 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { | 75 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { |
| 77 | v8::Locker locker(_v8Isolate); | 76 | return nullValue(); |
| 78 | v8::Isolate::Scope isolateScope(_v8Isolate); | ||
| 79 | v8::HandleScope handleScope(_v8Isolate); | ||
| 80 | v8::Context::Scope contextScope(getContext()); | ||
| 81 | return V8ScriptValue(this, v8::Null(_v8Isolate)); | ||
| 82 | } | 77 | } |
| 83 | v8::Locker locker(_v8Isolate); | 78 | v8::Locker locker(_v8Isolate); |
| 84 | v8::Isolate::Scope isolateScope(_v8Isolate); | 79 | v8::Isolate::Scope isolateScope(_v8Isolate); |
| 85 | v8::HandleScope handleScope(_v8Isolate); | 80 | v8::HandleScope handleScope(_v8Isolate); |
| 86 | v8::Context::Scope contextScope(getContext()); | 81 | v8::Context::Scope contextScope(getContext()); |
| 87 | return V8ScriptValue(this, v8::Null(_v8Isolate)); | 82 | return nullValue(); |
| 83 | } | ||
| 84 | |||
| 88 | //V8TODO | 85 | //V8TODO |
| 89 | /* | 86 | /* |
| 90 | auto other = _other; | 87 | auto other = _other; |
| @@ -117,33 +114,8 @@ V8ScriptValue ScriptEngineV8::makeError(const V8ScriptValue& _other, const QStri · 26 unmodified lines | |||
| 117 | err.setProperty(it.name(), it.value()); | 114 | err.setProperty(it.name(), it.value()); |
| 118 | } | 115 | } |
| 119 | return err;*/ | 116 | return err;*/ |
| 120 | } | 117 | //} |
| 121 | 118 | ||
| 122 | ScriptValue ScriptEngineV8::makeError(const ScriptValue& _other, const QString& type) { | ||
| 123 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { | ||
| 124 | return nullValue(); | ||
| 125 | } | ||
| 126 | v8::Locker locker(_v8Isolate); | ||
| 127 | v8::Isolate::Scope isolateScope(_v8Isolate); | ||
| 128 | v8::HandleScope handleScope(_v8Isolate); | ||
| 129 | v8::Context::Scope contextScope(getContext()); | ||
| 130 | return nullValue(); | ||
| 131 | |||
| 132 | //V8TODO | ||
| 133 | //what does makeError actually do? | ||
| 134 | /*ScriptValueV8Wrapper* unwrapped = ScriptValueV8Wrapper::unwrap(_other); | ||
| 135 | V8ScriptValue other; | ||
| 136 | if (_other.isString()) { | ||
| 137 | other = QScriptEngine::newObject(); | ||
| 138 | other.setProperty("message", _other.toString()); | ||
| 139 | } else if (unwrapped) { | ||
| 140 | other = unwrapped->toV8Value(); | ||
| 141 | } else { | ||
| 142 | other = QScriptEngine::newVariant(_other.toVariant()); | ||
| 143 | } | ||
| 144 | V8ScriptValue result = makeError(other, type); | ||
| 145 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(result)));*/ | ||
| 146 | } | ||
| 147 | 119 | ||
| 148 | // check syntax and when there are issues returns an actual "SyntaxError" with the details | 120 | // check syntax and when there are issues returns an actual "SyntaxError" with the details |
| 149 | ScriptValue ScriptEngineV8::checkScriptSyntax(ScriptProgramPointer program) { | 121 | ScriptValue ScriptEngineV8::checkScriptSyntax(ScriptProgramPointer program) { |
| @@ -200,82 +172,14 @@ ScriptValue ScriptEngineV8::checkScriptSyntax(ScriptProgramPointer program) { · 50 unmodified lines | |||
| 200 | return undefinedValue(); | 172 | return undefinedValue(); |
| 201 | }*/ | 173 | }*/ |
| 202 | 174 | ||
| 203 | // this pulls from the best available information to create a detailed snapshot of the current exception | ||
| 204 | ScriptValue ScriptEngineV8::cloneUncaughtException(const QString& extraDetail) { | ||
| 205 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { | ||
| 206 | return nullValue(); | ||
| 207 | } | ||
| 208 | if (!hasUncaughtException()) { | ||
| 209 | return nullValue(); | ||
| 210 | } | ||
| 211 | v8::Locker locker(_v8Isolate); | ||
| 212 | v8::Isolate::Scope isolateScope(_v8Isolate); | ||
| 213 | v8::HandleScope handleScope(_v8Isolate); | ||
| 214 | v8::Context::Scope contextScope(getContext()); | ||
| 215 | return nullValue(); | ||
| 216 | //V8TODO | ||
| 217 | /* | ||
| 218 | auto exception = uncaughtException(); | ||
| 219 | // ensure the error object is engine-local | ||
| 220 | auto err = makeError(exception); | ||
| 221 | |||
| 222 | // not sure why Qt does't offer uncaughtExceptionFileName -- but the line number | ||
| 223 | // on its own is often useless/wrong if arbitrarily married to a filename. | ||
| 224 | // when the error object already has this info, it seems to be the most reliable | ||
| 225 | auto fileName = exception.property("fileName").toString(); | ||
| 226 | auto lineNumber = exception.property("lineNumber").toInt32(); | ||
| 227 | |||
| 228 | // the backtrace, on the other hand, seems most reliable taken from uncaughtExceptionBacktrace | ||
| 229 | auto backtrace = uncaughtExceptionBacktrace(); | ||
| 230 | if (backtrace.isEmpty()) { | ||
| 231 | // fallback to the error object | ||
| 232 | backtrace = exception.property("stack").toString().split(ScriptManager::SCRIPT_BACKTRACE_SEP); | ||
| 233 | } | ||
| 234 | // the ad hoc "detail" property can be used now to embed additional clues | ||
| 235 | auto detail = exception.property("detail").toString(); | ||
| 236 | if (detail.isEmpty()) { | ||
| 237 | detail = extraDetail; | ||
| 238 | } else if (!extraDetail.isEmpty()) { | ||
| 239 | detail += "(" + extraDetail + ")"; | ||
| 240 | } | ||
| 241 | if (lineNumber <= 0) { | ||
| 242 | lineNumber = uncaughtExceptionLineNumber(); | ||
| 243 | } | ||
| 244 | if (fileName.isEmpty()) { | ||
| 245 | // climb the stack frames looking for something useful to display | ||
| 246 | for (auto c = QScriptEngine::currentContext(); c && fileName.isEmpty(); c = c->parentContext()) { | ||
| 247 | V8ScriptContextInfo info{ c }; | ||
| 248 | if (!info.fileName().isEmpty()) { | ||
| 249 | // take fileName:lineNumber as a pair | ||
| 250 | fileName = info.fileName(); | ||
| 251 | lineNumber = info.lineNumber(); | ||
| 252 | if (backtrace.isEmpty()) { | ||
| 253 | backtrace = c->backtrace(); | ||
| 254 | } | ||
| 255 | break; | ||
| 256 | } | ||
| 257 | } | ||
| 258 | } | ||
| 259 | err.setProperty("fileName", fileNlintame); | ||
| 260 | err.setProperty("lineNumber", lineNumber); | ||
| 261 | err.setProperty("detail", detail); | ||
| 262 | err.setProperty("stack", backtrace.join(ScriptManager::SCRIPT_BACKTRACE_SEP)); | ||
| 263 | |||
| 264 | #ifdef DEBUG_JS_EXCEPTIONS | ||
| 265 | err.setProperty("_fileName", exception.property("fileName").toString()); | ||
| 266 | err.setProperty("_stack", uncaughtExceptionBacktrace().join(SCRIPT_BACKTRACE_SEP)); | ||
| 267 | err.setProperty("_lineNumber", uncaughtExceptionLineNumber()); | ||
| 268 | #endif | ||
| 269 | return err; | ||
| 270 | */ | ||
| 271 | } | ||
| 272 | |||
| 273 | bool ScriptEngineV8::raiseException(const V8ScriptValue& exception) { | 175 | bool ScriptEngineV8::raiseException(const V8ScriptValue& exception) { |
| 274 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { | 176 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { |
| 275 | return false; | 177 | return false; |
| 276 | } | 178 | } |
| 277 | //V8TODO | 179 | //V8TODO |
| 278 | _v8Isolate->ThrowException(makeError(exception).get()); | 180 | // _v8Isolate->ThrowException(makeError(exception).get()); |
| 181 | |||
| 182 | |||
| 279 | /*if (QScriptEngine::currentContext()) { | 183 | /*if (QScriptEngine::currentContext()) { |
| 280 | // we have an active context / JS stack frame so throw the exception per usual | 184 | // we have an active context / JS stack frame so throw the exception per usual |
| 281 | QScriptEngine::currentContext()->throwValue(makeError(exception)); | 185 | QScriptEngine::currentContext()->throwValue(makeError(exception)); |
| @@ -290,22 +194,6 @@ bool ScriptEngineV8::raiseException(const V8ScriptValue& exception) { · 8 unmodified lines | |||
| 290 | return false; | 194 | return false; |
| 291 | } | 195 | } |
| 292 | 196 | ||
| 293 | bool ScriptEngineV8::maybeEmitUncaughtException(const QString& debugHint) { | ||
| 294 | |||
| 295 | /* | ||
| 296 | if (!IS_THREADSAFE_INVOCATION(thread(), __FUNCTION__)) { | ||
| 297 | return false; | ||
| 298 | } | ||
| 299 | if (!isEvaluating() && hasUncaughtException()) { | ||
| 300 | emit exception(cloneUncaughtException(debugHint)); | ||
| 301 | clearExceptions(); | ||
| 302 | return true; | ||
| 303 | } | ||
| 304 | |||
| 305 | */ | ||
| 306 | return false; | ||
| 307 | } | ||
| 308 | |||
| 309 | // Lambda | 197 | // Lambda |
| 310 | /*ScriptValue ScriptEngineV8::newLambdaFunction(std::function<V8ScriptValue(V8ScriptContext*, ScriptEngineV8*)> operation, | 198 | /*ScriptValue ScriptEngineV8::newLambdaFunction(std::function<V8ScriptValue(V8ScriptContext*, ScriptEngineV8*)> operation, |
| 311 | const V8ScriptValue& data, | 199 | const V8ScriptValue& data, |
| @@ -1019,12 +907,11 @@ ScriptValue ScriptEngineV8::evaluateInClosure(const ScriptValue& _closure, · 707 unmodified lines | |||
| 1019 | } | 907 | } |
| 1020 | 908 | ||
| 1021 | if (hasUncaughtException()) { | 909 | if (hasUncaughtException()) { |
| 1022 | auto err = cloneUncaughtException(__FUNCTION__); | ||
| 1023 | #ifdef DEBUG_JS_EXCEPTIONS | 910 | #ifdef DEBUG_JS_EXCEPTIONS |
| 1024 | qCWarning(shared) << __FUNCTION__ << "---------- hasCaught:" << err.toString() << result.toString(); | 911 | qCWarning(shared) << __FUNCTION__ << "---------- hasCaught:" << err.toString() << result.toString(); |
| 1025 | err.setProperty("_result", result); | 912 | err.setProperty("_result", result); |
| 1026 | #endif | 913 | #endif |
| 1027 | result = err; | 914 | result = nullValue(); |
| 1028 | } else { | 915 | } else { |
| 1029 | result = ScriptValue(new ScriptValueV8Wrapper(this, V8ScriptValue(this, v8Result))); | 916 | result = ScriptValue(new ScriptValueV8Wrapper(this, V8ScriptValue(this, v8Result))); |
| 1030 | } | 917 | } |
| @@ -1073,34 +960,9 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f · 42 unmodified lines | |||
| 1073 | v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(), fileName.toStdString().c_str()).ToLocalChecked()); | 960 | v8::ScriptOrigin scriptOrigin(getIsolate(), v8::String::NewFromUtf8(getIsolate(), fileName.toStdString().c_str()).ToLocalChecked()); |
| 1074 | v8::Local<v8::Script> script; | 961 | v8::Local<v8::Script> script; |
| 1075 | if (!v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) { | 962 | if (!v8::Script::Compile(getContext(), v8::String::NewFromUtf8(getIsolate(), sourceCode.toStdString().c_str()).ToLocalChecked(), &scriptOrigin).ToLocal(&script)) { |
| 1076 | //V8TODO replace this with external function | 963 | setUncaughtException(tryCatch, "Error while compiling script"); |
| 1077 | int errorColumnNumber = 0; | ||
| 1078 | int errorLineNumber = 0; | ||
| 1079 | QString errorMessage = ""; | ||
| 1080 | QString errorBacktrace = ""; | ||
| 1081 | //v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Exception()); | ||
| 1082 | v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Message()->Get()); | ||
| 1083 | errorMessage = QString(*utf8Value); | ||
| 1084 | v8::Local<v8::Message> exceptionMessage = tryCatch.Message(); | ||
| 1085 | if (!exceptionMessage.IsEmpty()) { | ||
| 1086 | errorLineNumber = exceptionMessage->GetLineNumber(getContext()).FromJust(); | ||
| 1087 | errorColumnNumber = exceptionMessage->GetStartColumn(getContext()).FromJust(); | ||
| 1088 | v8::Local<v8::Value> backtraceV8String; | ||
| 1089 | if (tryCatch.StackTrace(getContext()).ToLocal(&backtraceV8String)) { | ||
| 1090 | if (backtraceV8String->IsString()) { | ||
| 1091 | if (v8::Local<v8::String>::Cast(backtraceV8String)->Length() > 0) { | ||
| 1092 | v8::String::Utf8Value backtraceUtf8Value(getIsolate(), backtraceV8String); | ||
| 1093 | errorBacktrace = *backtraceUtf8Value; | ||
| 1094 | } | ||
| 1095 | } | ||
| 1096 | } | ||
| 1097 | qCDebug(scriptengine) << "Compiling script \"" << fileName << "\" failed on line " << errorLineNumber << " column " << errorColumnNumber << " with message: \"" << errorMessage <<"\" backtrace: " << errorBacktrace; | ||
| 1098 | } | ||
| 1099 | auto err = makeError(newValue(errorMessage)); | ||
| 1100 | raiseException(err); | ||
| 1101 | maybeEmitUncaughtException("compile"); | ||
| 1102 | _evaluatingCounter--; | 964 | _evaluatingCounter--; |
| 1103 | return err; | 965 | return nullValue(); |
| 1104 | } | 966 | } |
| 1105 | //qCDebug(scriptengine) << "Script compilation succesful: " << fileName; | 967 | //qCDebug(scriptengine) << "Script compilation succesful: " << fileName; |
| 1106 | 968 | ||
| @@ -1145,6 +1007,12 @@ ScriptValue ScriptEngineV8::evaluate(const QString& sourceCode, const QString& f · 38 unmodified lines | |||
| 1145 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValue))); | 1007 | return ScriptValue(new ScriptValueV8Wrapper(this, std::move(resultValue))); |
| 1146 | } | 1008 | } |
| 1147 | 1009 | ||
| 1010 | |||
| 1011 | void ScriptEngineV8::setUncaughtEngineException(const QString &reason, const QString& info) { | ||
| 1012 | auto ex = std::make_shared<ScriptEngineException>(reason, info); | ||
| 1013 | setUncaughtException(ex); | ||
| 1014 | } | ||
| 1015 | |||
| 1148 | void ScriptEngineV8::setUncaughtException(const v8::TryCatch &tryCatch, const QString& info) { | 1016 | void ScriptEngineV8::setUncaughtException(const v8::TryCatch &tryCatch, const QString& info) { |
| 1149 | if (!tryCatch.HasCaught()) { | 1017 | if (!tryCatch.HasCaught()) { |
| 1150 | qCWarning(scriptengine) << "setUncaughtException called without exception"; | 1018 | qCWarning(scriptengine) << "setUncaughtException called without exception"; |
| @@ -1152,8 +1020,8 @@ void ScriptEngineV8::setUncaughtException(const v8::TryCatch &tryCatch, const QS · 1 unmodified line | |||
| 1152 | return; | 1020 | return; |
| 1153 | } | 1021 | } |
| 1154 | 1022 | ||
| 1155 | ScriptException ex; | 1023 | auto ex = std::make_shared<ScriptException>(); |
| 1156 | ex.additionalInfo = info; | 1024 | ex->additionalInfo = info; |
| 1157 | 1025 | ||
| 1158 | v8::Locker locker(_v8Isolate); | 1026 | v8::Locker locker(_v8Isolate); |
| 1159 | v8::Isolate::Scope isolateScope(_v8Isolate); | 1027 | v8::Isolate::Scope isolateScope(_v8Isolate); |
| @@ -1166,30 +1034,35 @@ void ScriptEngineV8::setUncaughtException(const v8::TryCatch &tryCatch, const QS · 6 unmodified lines | |||
| 1166 | //v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Exception()); | 1034 | //v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Exception()); |
| 1167 | v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Message()->Get()); | 1035 | v8::String::Utf8Value utf8Value(getIsolate(), tryCatch.Message()->Get()); |
| 1168 | 1036 | ||
| 1169 | ex.errorMessage = QString(*utf8Value); | 1037 | ex->errorMessage = QString(*utf8Value); |
| 1170 | 1038 | ||
| 1171 | v8::Local<v8::Message> exceptionMessage = tryCatch.Message(); | 1039 | v8::Local<v8::Message> exceptionMessage = tryCatch.Message(); |
| 1172 | if (!exceptionMessage.IsEmpty()) { | 1040 | if (!exceptionMessage.IsEmpty()) { |
| 1173 | ex.errorLine = exceptionMessage->GetLineNumber(getContext()).FromJust(); | 1041 | ex->errorLine = exceptionMessage->GetLineNumber(getContext()).FromJust(); |
| 1174 | ex.errorColumn = exceptionMessage->GetStartColumn(getContext()).FromJust(); | 1042 | ex->errorColumn = exceptionMessage->GetStartColumn(getContext()).FromJust(); |
| 1175 | v8::Local<v8::Value> backtraceV8String; | 1043 | v8::Local<v8::Value> backtraceV8String; |
| 1176 | if (tryCatch.StackTrace(getContext()).ToLocal(&backtraceV8String)) { | 1044 | if (tryCatch.StackTrace(getContext()).ToLocal(&backtraceV8String)) { |
| 1177 | if (backtraceV8String->IsString()) { | 1045 | if (backtraceV8String->IsString()) { |
| 1178 | if (v8::Local<v8::String>::Cast(backtraceV8String)->Length() > 0) { | 1046 | if (v8::Local<v8::String>::Cast(backtraceV8String)->Length() > 0) { |
| 1179 | v8::String::Utf8Value backtraceUtf8Value(getIsolate(), backtraceV8String); | 1047 | v8::String::Utf8Value backtraceUtf8Value(getIsolate(), backtraceV8String); |
| 1180 | QString errorBacktrace = *backtraceUtf8Value; | 1048 | QString errorBacktrace = *backtraceUtf8Value; |
| 1181 | ex.backtrace = errorBacktrace.split("\n"); | 1049 | ex->backtrace = errorBacktrace.split("\n"); |
| 1182 | 1050 | ||
| 1183 | } | 1051 | } |
| 1184 | } | 1052 | } |
| 1185 | } | 1053 | } |
| 1186 | } | 1054 | } |
| 1187 | 1055 | ||
| 1188 | qCDebug(scriptengine) << "Emitting exception:" << ex; | 1056 | setUncaughtException(ex); |
| 1189 | _uncaughtException = ex; | ||
| 1190 | emit exception(ex); | ||
| 1191 | } | 1057 | } |
| 1192 | 1058 | ||
| 1059 | void ScriptEngineV8::setUncaughtException(std::shared_ptr<ScriptException> uncaughtException) { | ||
| 1060 | qCDebug(scriptengine) << "Emitting exception:" << uncaughtException; | ||
| 1061 | _uncaughtException = uncaughtException; | ||
| 1062 | |||
| 1063 | auto copy = uncaughtException->clone(); | ||
| 1064 | emit exception(copy); | ||
| 1065 | } | ||
| 1193 | 1066 | ||
| 1194 | 1067 | ||
| 1195 | QString ScriptEngineV8::formatErrorMessageFromTryCatch(v8::TryCatch &tryCatch) { | 1068 | QString ScriptEngineV8::formatErrorMessageFromTryCatch(v8::TryCatch &tryCatch) { |
| @@ -1274,18 +1147,14 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro · 78 unmodified lines | |||
| 1274 | v8::Context::Scope contextScope(getContext()); | 1147 | v8::Context::Scope contextScope(getContext()); |
| 1275 | ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program); | 1148 | ScriptProgramV8Wrapper* unwrapped = ScriptProgramV8Wrapper::unwrap(program); |
| 1276 | if (!unwrapped) { | 1149 | if (!unwrapped) { |
| 1277 | errorValue = makeError(newValue("could not unwrap program")); | 1150 | setUncaughtEngineException("Could not unwrap program", "Compile error"); |
| 1278 | raiseException(errorValue); | ||
| 1279 | maybeEmitUncaughtException("compile"); | ||
| 1280 | hasFailed = true; | 1151 | hasFailed = true; |
| 1281 | } | 1152 | } |
| 1282 | 1153 | ||
| 1283 | if(!hasFailed) { | 1154 | if(!hasFailed) { |
| 1284 | ScriptSyntaxCheckResultPointer syntaxCheck = unwrapped->checkSyntax(); | 1155 | ScriptSyntaxCheckResultPointer syntaxCheck = unwrapped->checkSyntax(); |
| 1285 | if (syntaxCheck->state() == ScriptSyntaxCheckResult::Error) { | 1156 | if (syntaxCheck->state() == ScriptSyntaxCheckResult::Error) { |
| 1286 | errorValue = makeError(newValue(syntaxCheck->errorMessage())); | 1157 | setUncaughtEngineException(syntaxCheck->errorMessage(), "Compile error"); |
| 1287 | raiseException(errorValue); | ||
| 1288 | maybeEmitUncaughtException("compile"); | ||
| 1289 | hasFailed = true; | 1158 | hasFailed = true; |
| 1290 | } | 1159 | } |
| 1291 | } | 1160 | } |
| @@ -1307,8 +1176,7 @@ Q_INVOKABLE ScriptValue ScriptEngineV8::evaluate(const ScriptProgramPointer& pro · 15 unmodified lines | |||
| 1307 | Q_ASSERT(tryCatchRun.HasCaught()); | 1176 | Q_ASSERT(tryCatchRun.HasCaught()); |
| 1308 | auto runError = tryCatchRun.Message(); | 1177 | auto runError = tryCatchRun.Message(); |
| 1309 | errorValue = ScriptValue(new ScriptValueV8Wrapper(this, V8ScriptValue(this, runError->Get()))); | 1178 | errorValue = ScriptValue(new ScriptValueV8Wrapper(this, V8ScriptValue(this, runError->Get()))); |
| 1310 | raiseException(errorValue); | 1179 | raiseException(errorValue, "evaluation error"); |
| 1311 | maybeEmitUncaughtException("evaluate"); | ||
| 1312 | hasFailed = true; | 1180 | hasFailed = true; |
| 1313 | } else { | 1181 | } else { |
| 1314 | // V8TODO this is just to check if run will always return false for uncaught exception | 1182 | // V8TODO this is just to check if run will always return false for uncaught exception |
| @@ -1529,7 +1397,7 @@ void ScriptEngineV8::abortEvaluation() { · 214 unmodified lines | |||
| 1529 | } | 1397 | } |
| 1530 | 1398 | ||
| 1531 | void ScriptEngineV8::clearExceptions() { | 1399 | void ScriptEngineV8::clearExceptions() { |
| 1532 | _uncaughtException = ScriptException(); | 1400 | _uncaughtException.reset(); |
| 1533 | } | 1401 | } |
| 1534 | 1402 | ||
| 1535 | ScriptContext* ScriptEngineV8::currentContext() const { | 1403 | ScriptContext* ScriptEngineV8::currentContext() const { |
| @@ -1551,7 +1419,7 @@ ScriptContext* ScriptEngineV8::currentContext() const { · 15 unmodified lines | |||
| 1551 | } | 1419 | } |
| 1552 | 1420 | ||
| 1553 | bool ScriptEngineV8::hasUncaughtException() const { | 1421 | bool ScriptEngineV8::hasUncaughtException() const { |
| 1554 | return !_uncaughtException.isEmpty(); | 1422 | return _uncaughtException != nullptr; |
| 1555 | } | 1423 | } |
| 1556 | 1424 | ||
| 1557 | bool ScriptEngineV8::isEvaluating() const { | 1425 | bool ScriptEngineV8::isEvaluating() const { |
| @@ -1667,11 +1535,15 @@ void ScriptEngineV8::setThread(QThread* thread) { · 109 unmodified lines | |||
| 1667 | }*/ | 1535 | }*/ |
| 1668 | 1536 | ||
| 1669 | 1537 | ||
| 1670 | ScriptException ScriptEngineV8::uncaughtException() const { | 1538 | std::shared_ptr<ScriptException> ScriptEngineV8::uncaughtException() const { |
| 1671 | return _uncaughtException; | 1539 | return _uncaughtException->clone(); |
| 1540 | } | ||
| 1541 | |||
| 1542 | bool ScriptEngineV8::raiseException(const QString& error, const QString &reason) { | ||
| 1543 | return raiseException(ScriptValue(), reason); | ||
| 1672 | } | 1544 | } |
| 1673 | 1545 | ||
| 1674 | bool ScriptEngineV8::raiseException(const ScriptValue& exception) { | 1546 | bool ScriptEngineV8::raiseException(const ScriptValue& exception, const QString &reason) { |
| 1675 | //V8TODO | 1547 | //V8TODO |
| 1676 | //Q_ASSERT(false); | 1548 | //Q_ASSERT(false); |
| 1677 | // qCritical() << "Script exception occurred: " << exception.toString(); | 1549 | // qCritical() << "Script exception occurred: " << exception.toString(); |
| @@ -1681,6 +1553,7 @@ bool ScriptEngineV8::raiseException(const ScriptValue& exception) { · 3 unmodified lines | |||
| 1681 | // emit | 1553 | // emit |
| 1682 | //return raiseException(qException); | 1554 | //return raiseException(qException); |
| 1683 | 1555 | ||
| 1556 | qCCritical(scriptengine) << "Raise exception for reason" << reason << "NOT IMPLEMENTED!"; | ||
| 1684 | return false; | 1557 | return false; |
| 1685 | } | 1558 | } |
| 1686 | 1559 | ||