History

classify ScriptEngine errors better, and send them as signal to JS

Brad Hefta-Gaub committed 9 years ago

Commit 6a7fa631 parent c65471e6 files · +108 −41Browse files

Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 6 files). Show all

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+58−40
@@ -86,6 +86,8 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){ · 85 unmodified lines
8686 .replace("\n", "\\n")
8787 .replace("\r", "\\r")
8888 .replace("'", "\\'");
89+
90+ // FIXME - this approach neeeds revisiting. print() comes here, which ends up doing an evaluate?
8991 engine->evaluate("Script.print('" + message + "')");
9092
9193 return QScriptValue();
@@ -130,20 +132,20 @@ QString encodeEntityIdIntoEntityUrl(const QString& url, const QString& entityID) · 38 unmodified lines
130132 return url + " [EntityID:" + entityID + "]";
131133 }
132134
133−static bool hasCorrectSyntax(const QScriptProgram& program) {
135+static bool hasCorrectSyntax(const QScriptProgram& program, ScriptEngine* reportingEngine) {
134136 const auto syntaxCheck = QScriptEngine::checkSyntax(program.sourceCode());
135137 if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
136138 const auto error = syntaxCheck.errorMessage();
137139 const auto line = QString::number(syntaxCheck.errorLineNumber());
138140 const auto column = QString::number(syntaxCheck.errorColumnNumber());
139141 const auto message = QString("[SyntaxError] %1 in %2:%3(%4)").arg(error, program.fileName(), line, column);
140− qCWarning(scriptengine) << qPrintable(message);
142+ reportingEngine->scriptErrorMessage(qPrintable(message));
141143 return false;
142144 }
143145 return true;
144146 }
145147
146−static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName) {
148+static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName, ScriptEngine* reportingEngine) {
147149 if (engine.hasUncaughtException()) {
148150 const auto backtrace = engine.uncaughtExceptionBacktrace();
149151 const auto exception = engine.uncaughtException().toString();
@@ -155,7 +157,7 @@ static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName · 5 unmodified lines
155157 static const auto lineSeparator = "\n ";
156158 message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator));
157159 }
158− qCWarning(scriptengine) << qPrintable(message);
160+ reportingEngine->scriptErrorMessage(qPrintable(message));
159161 return true;
160162 }
161163 return false;
@@ -170,20 +172,20 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam · 8 unmodified lines
170172 DependencyManager::get<ScriptEngines>()->addScriptEngine(this);
171173
172174 connect(this, &QScriptEngine::signalHandlerException, this, [this](const QScriptValue& exception) {
173− hadUncaughtExceptions(*this, _fileNameString);
175+ hadUncaughtExceptions(*this, _fileNameString, this);
174176 });
175177
176178 setProcessEventsInterval(MSECS_PER_SECOND);
177179 }
178180
179181 ScriptEngine::~ScriptEngine() {
180− qCDebug(scriptengine) << "Script Engine shutting down:" << getFilename();
182+ scriptInfoMessage("Script Engine shutting down:" + getFilename());
181183
182184 auto scriptEngines = DependencyManager::get<ScriptEngines>();
183185 if (scriptEngines) {
184186 scriptEngines->removeScriptEngine(this);
185187 } else {
186− qCWarning(scriptengine) << "Script destroyed after ScriptEngines!";
188+ scriptWarningMessage("Script destroyed after ScriptEngines!");
187189 }
188190 }
189191
@@ -274,7 +276,7 @@ void ScriptEngine::runDebuggable() { · 84 unmodified lines
274276 }
275277 _lastUpdate = now;
276278 // Debug and clear exceptions
277− hadUncaughtExceptions(*this, _fileNameString);
279+ hadUncaughtExceptions(*this, _fileNameString, this);
278280 });
279281
280282 timer->start(10);
@@ -359,7 +361,7 @@ void ScriptEngine::waitTillDoneRunning() { · 78 unmodified lines
359361 QThread::yieldCurrentThread();
360362 }
361363
362− qCDebug(scriptengine) << "Script Engine has stopped:" << getFilename();
364+ scriptInfoMessage("Script Engine has stopped:" + getFilename());
363365 }
364366 }
365367
@@ -398,10 +400,25 @@ void ScriptEngine::scriptContentsAvailable(const QUrl& url, const QString& scrip · 32 unmodified lines
398400 emit scriptLoaded(url.toString());
399401 }
400402
403+void ScriptEngine::scriptErrorMessage(const QString& message) {
404+ qCCritical(scriptengine) << message;
405+ emit errorMessage(message);
406+}
407+
408+void ScriptEngine::scriptWarningMessage(const QString& message) {
409+ qCWarning(scriptengine) << message;
410+ emit warningMessage(message);
411+}
412+
413+void ScriptEngine::scriptInfoMessage(const QString& message) {
414+ qCInfo(scriptengine) << message;
415+ emit infoMessage(message);
416+}
417+
401418 // FIXME - switch this to the new model of ScriptCache callbacks
402419 void ScriptEngine::errorInLoadingScript(const QUrl& url) {
403− qCDebug(scriptengine) << "ERROR Loading file:" << url.toString() << "line:" << __LINE__;
404− emit errorLoadingScript(_fileNameString); // ??
420+ scriptErrorMessage("ERROR Loading file:" + url.toString());
421+ emit errorLoadingScript(_fileNameString);
405422 }
406423
407424 // Even though we never pass AnimVariantMap directly to and from javascript, the queued invokeMethod of
@@ -809,7 +826,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi · 401 unmodified lines
809826
810827 // Check syntax
811828 const QScriptProgram program(sourceCode, fileName, lineNumber);
812− if (!hasCorrectSyntax(program)) {
829+ if (!hasCorrectSyntax(program, this)) {
813830 return QScriptValue();
814831 }
815832
@@ -817,7 +834,7 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi · 1 unmodified line
817834 const auto result = QScriptEngine::evaluate(program);
818835 --_evaluatesPending;
819836
820− const auto hadUncaughtException = hadUncaughtExceptions(*this, program.fileName());
837+ const auto hadUncaughtException = hadUncaughtExceptions(*this, program.fileName(), this);
821838 emit evaluationFinished(result, hadUncaughtException);
822839 return result;
823840 }
@@ -934,10 +951,10 @@ void ScriptEngine::run() { · 110 unmodified lines
934951 _lastUpdate = now;
935952
936953 // Debug and clear exceptions
937− hadUncaughtExceptions(*this, _fileNameString);
954+ hadUncaughtExceptions(*this, _fileNameString, this);
938955 }
939956
940− qCDebug(scriptengine) << "Script Engine stopping:" << getFilename();
957+ scriptInfoMessage("Script Engine stopping:" + getFilename());
941958
942959 stopAllTimers(); // make sure all our timers are stopped if the script is ending
943960 emit scriptEnding();
@@ -1044,7 +1061,7 @@ void ScriptEngine::timerFired() { · 100 unmodified lines
10441061 {
10451062 auto engine = DependencyManager::get<ScriptEngines>();
10461063 if (!engine || engine->isStopped()) {
1047− qCDebug(scriptengine) << "Script.timerFired() while shutting down is ignored... parent script:" << getFilename();
1064+ scriptWarningMessage("Script.timerFired() while shutting down is ignored... parent script:" + getFilename());
10481065 return; // bail early
10491066 }
10501067 }
@@ -1084,7 +1101,7 @@ QObject* ScriptEngine::setupTimerWithInterval(const QScriptValue& function, int · 33 unmodified lines
10841101
10851102 QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) {
10861103 if (DependencyManager::get<ScriptEngines>()->isStopped()) {
1087− qCDebug(scriptengine) << "Script.setInterval() while shutting down is ignored... parent script:" << getFilename();
1104+ scriptWarningMessage("Script.setInterval() while shutting down is ignored... parent script:" + getFilename());
10881105 return NULL; // bail early
10891106 }
10901107
@@ -1093,7 +1110,7 @@ QObject* ScriptEngine::setInterval(const QScriptValue& function, int intervalMS) · 2 unmodified lines
10931110
10941111 QObject* ScriptEngine::setTimeout(const QScriptValue& function, int timeoutMS) {
10951112 if (DependencyManager::get<ScriptEngines>()->isStopped()) {
1096− qCDebug(scriptengine) << "Script.setTimeout() while shutting down is ignored... parent script:" << getFilename();
1113+ scriptWarningMessage("Script.setTimeout() while shutting down is ignored... parent script:" + getFilename());
10971114 return NULL; // bail early
10981115 }
10991116
@@ -1153,8 +1170,8 @@ void ScriptEngine::print(const QString& message) { · 53 unmodified lines
11531170 // all of the files have finished loading.
11541171 void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callback) {
11551172 if (DependencyManager::get<ScriptEngines>()->isStopped()) {
1156− qCDebug(scriptengine) << "Script.include() while shutting down is ignored..."
1157− << "includeFiles:" << includeFiles << "parent script:" << getFilename();
1173+ scriptWarningMessage("Script.include() while shutting down is ignored... includeFiles:"
1174+ + includeFiles.join(",") + "parent script:" + getFilename());
11581175 return; // bail early
11591176 }
11601177 QList<QUrl> urls;
@@ -1182,7 +1199,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 21 unmodified lines
11821199 thisURL = expandScriptUrl(QUrl::fromLocalFile(expandScriptPath(file)));
11831200 QUrl defaultScriptsLoc = defaultScriptsLocation();
11841201 if (!defaultScriptsLoc.isParentOf(thisURL)) {
1185− qCDebug(scriptengine) << "ScriptEngine::include -- skipping" << file << "-- outside of standard libraries";
1202+ scriptWarningMessage("Script.include() -- skipping" + file + "-- outside of standard libraries");
11861203 continue;
11871204 }
11881205 isStandardLibrary = true;
@@ -1193,8 +1210,9 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 4 unmodified lines
11931210 if (!isStandardLibrary && !currentSandboxURL.isEmpty() && (thisURL.scheme() == "file") &&
11941211 (currentSandboxURL.scheme() != "file" ||
11951212 !thisURL.toString(strippingFlags).startsWith(currentSandboxURL.toString(strippingFlags), getSensitivity()))) {
1196− qCWarning(scriptengine) << "Script.include() ignoring file path"
1197− << thisURL << "outside of original entity script" << currentSandboxURL;
1213+
1214+ scriptWarningMessage("Script.include() ignoring file path" + thisURL.toString()
1215+ + "outside of original entity script" + currentSandboxURL.toString());
11981216 } else {
11991217 // We could also check here for CORS, but we don't yet.
12001218 // It turns out that QUrl.resolve will not change hosts and copy authority, so we don't need to check that here.
@@ -1216,7 +1234,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 15 unmodified lines
12161234 for (QUrl url : urls) {
12171235 QString contents = data[url];
12181236 if (contents.isNull()) {
1219− qCDebug(scriptengine) << "Error loading file: " << url << "line:" << __LINE__;
1237+ scriptErrorMessage("Error loading file: " + url.toString());
12201238 } else {
12211239 std::lock_guard<std::recursive_mutex> lock(_lock);
12221240 if (!_includedURLs.contains(url)) {
@@ -1230,7 +1248,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 7 unmodified lines
12301248
12311249 doWithEnvironment(capturedEntityIdentifier, capturedSandboxURL, operation);
12321250 } else {
1233− qCDebug(scriptengine) << "Script.include() skipping evaluation of previously included url:" << url;
1251+ scriptWarningMessage("Script.include() skipping evaluation of previously included url:" + url.toString());
12341252 }
12351253 }
12361254 }
@@ -1259,8 +1277,8 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac · 22 unmodified lines
12591277
12601278 void ScriptEngine::include(const QString& includeFile, QScriptValue callback) {
12611279 if (DependencyManager::get<ScriptEngines>()->isStopped()) {
1262− qCDebug(scriptengine) << "Script.include() while shutting down is ignored... "
1263− << "includeFile:" << includeFile << "parent script:" << getFilename();
1280+ scriptWarningMessage("Script.include() while shutting down is ignored... includeFile:"
1281+ + includeFile + "parent script:" + getFilename());
12641282 return; // bail early
12651283 }
12661284
@@ -1274,13 +1292,13 @@ void ScriptEngine::include(const QString& includeFile, QScriptValue callback) { · 7 unmodified lines
12741292 // the Application or other context will connect to in order to know to actually load the script
12751293 void ScriptEngine::load(const QString& loadFile) {
12761294 if (DependencyManager::get<ScriptEngines>()->isStopped()) {
1277− qCDebug(scriptengine) << "Script.load() while shutting down is ignored... "
1278− << "loadFile:" << loadFile << "parent script:" << getFilename();
1295+ scriptWarningMessage("Script.load() while shutting down is ignored... loadFile:"
1296+ + loadFile + "parent script:" + getFilename());
12791297 return; // bail early
12801298 }
12811299 if (!currentEntityIdentifier.isInvalidID()) {
1282− qCWarning(scriptengine) << "Script.load() from entity script is ignored... "
1283− << "loadFile:" << loadFile << "parent script:" << getFilename();
1300+ scriptWarningMessage("Script.load() from entity script is ignored... loadFile:"
1301+ + loadFile + "parent script:" + getFilename());
12841302 return; // bail early
12851303 }
12861304
@@ -1368,7 +1386,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 81 unmodified lines
13681386 auto fileName = isURL ? scriptOrURL : "EmbeddedEntityScript";
13691387
13701388 QScriptProgram program(contents, fileName);
1371− if (!hasCorrectSyntax(program)) {
1389+ if (!hasCorrectSyntax(program, this)) {
13721390 if (!isFileUrl) {
13731391 scriptCache->addScriptToBadScriptList(scriptOrURL);
13741392 }
@@ -1396,7 +1414,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 21 unmodified lines
13961414 });
13971415 testConstructor = sandbox.evaluate(program);
13981416 }
1399− if (hadUncaughtExceptions(sandbox, program.fileName())) {
1417+ if (hadUncaughtExceptions(sandbox, program.fileName(), this)) {
14001418 return;
14011419 }
14021420
@@ -1410,10 +1428,10 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 7 unmodified lines
14101428 if (testConstructorValue.size() > maxTestConstructorValueSize) {
14111429 testConstructorValue = testConstructorValue.mid(0, maxTestConstructorValueSize) + "...";
14121430 }
1413− qCDebug(scriptengine) << "Error -- ScriptEngine::loadEntityScript() entity:" << entityID
1414− << "failed to load entity script -- expected a function, got " + testConstructorType
1415− << "," << testConstructorValue
1416− << "," << scriptOrURL;
1431+ scriptErrorMessage("Error -- ScriptEngine::loadEntityScript() entity:" + entityID.toString()
1432+ + "failed to load entity script -- expected a function, got " + testConstructorType
1433+ + "," + testConstructorValue
1434+ + "," + scriptOrURL);
14171435
14181436 if (!isFileUrl) {
14191437 scriptCache->addScriptToBadScriptList(scriptOrURL);
@@ -1513,7 +1531,7 @@ void ScriptEngine::refreshFileScript(const EntityItemID& entityID) { · 93 unmodified lines
15131531 QString filePath = QUrl(details.scriptText).toLocalFile();
15141532 auto lastModified = QFileInfo(filePath).lastModified().toMSecsSinceEpoch();
15151533 if (lastModified > details.lastModified) {
1516− qCDebug(scriptengine) << "Reloading modified script " << details.scriptText;
1534+ scriptInfoMessage("Reloading modified script " + details.scriptText);
15171535
15181536 QFile file(filePath);
15191537 file.open(QIODevice::ReadOnly);
@@ -1521,7 +1539,7 @@ void ScriptEngine::refreshFileScript(const EntityItemID& entityID) { · 1 unmodified line
15211539 this->unloadEntityScript(entityID);
15221540 this->entityScriptContentAvailable(entityID, details.scriptText, scriptContents, true, true);
15231541 if (!_entityScripts.contains(entityID)) {
1524− qWarning() << "Reload script " << details.scriptText << " failed";
1542+ scriptWarningMessage("Reload script " + details.scriptText + " failed");
15251543 } else {
15261544 details = _entityScripts[entityID];
15271545 }
@@ -1548,7 +1566,7 @@ void ScriptEngine::doWithEnvironment(const EntityItemID& entityID, const QUrl& s · 20 unmodified lines
15481566 #else
15491567 operation();
15501568 #endif
1551− hadUncaughtExceptions(*this, _fileNameString);
1569+ hadUncaughtExceptions(*this, _fileNameString, this);
15521570
15531571 currentEntityIdentifier = oldIdentifier;
15541572 currentSandboxURL = oldSandboxURL;