From b6a94db929a1f8503c2b516c5114a73181b8799a Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 2 Oct 2017 16:32:03 +0200 Subject: Fix missing error location in case of syntax errors in scripts We used a backtrace whenever one was available, but if it contains no error location, it actually decreases the usefulness of the error message. In such cases, ignore it and use the fallback error location instead. Change-Id: I7da6a7cf2ddce17f6c1da82fbc4a08148b26e2b4 Reviewed-by: Jake Petroules Reviewed-by: Joerg Bornemann --- src/lib/corelib/language/scriptengine.cpp | 7 +++++-- src/lib/corelib/tools/error.cpp | 6 ++++++ src/lib/corelib/tools/error.h | 1 + tests/auto/language/testdata/erroneous/syntax-error-in-probe.qbs | 8 ++++++++ tests/auto/language/tst_language.cpp | 2 ++ 5 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 tests/auto/language/testdata/erroneous/syntax-error-in-probe.qbs diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp index cfbaf9b69..7ed7f4da1 100644 --- a/src/lib/corelib/language/scriptengine.cpp +++ b/src/lib/corelib/language/scriptengine.cpp @@ -544,8 +544,11 @@ ErrorInfo ScriptEngine::lastError(const QScriptValue &v, const CodeLocation &fal if (errorLocation.isValid()) return ErrorInfo(msg, errorLocation); const QStringList backtrace = uncaughtExceptionBacktraceOrEmpty(); - if (!backtrace.isEmpty()) - return ErrorInfo(msg, backtrace); + if (!backtrace.isEmpty()) { + ErrorInfo e(msg, backtrace); + if (e.hasLocation()) + return e; + } return ErrorInfo(msg, fallbackLocation); } diff --git a/src/lib/corelib/tools/error.cpp b/src/lib/corelib/tools/error.cpp index 719b985f1..60394ca6e 100644 --- a/src/lib/corelib/tools/error.cpp +++ b/src/lib/corelib/tools/error.cpp @@ -272,6 +272,12 @@ bool ErrorInfo::isInternalError() const return d->internalError; } +bool ErrorInfo::hasLocation() const +{ + return std::any_of(d->items.cbegin(), d->items.cend(), + [](const ErrorItem &ei) { return ei.codeLocation().isValid(); }); +} + void ErrorInfo::load(Internal::PersistentPool &pool) { pool.load(d->items); diff --git a/src/lib/corelib/tools/error.h b/src/lib/corelib/tools/error.h index a6a5711cb..3891a0eb4 100644 --- a/src/lib/corelib/tools/error.h +++ b/src/lib/corelib/tools/error.h @@ -99,6 +99,7 @@ public: void clear(); QString toString() const; bool isInternalError() const; + bool hasLocation() const; void load(Internal::PersistentPool &pool); void store(Internal::PersistentPool &pool) const; diff --git a/tests/auto/language/testdata/erroneous/syntax-error-in-probe.qbs b/tests/auto/language/testdata/erroneous/syntax-error-in-probe.qbs new file mode 100644 index 000000000..e81274395 --- /dev/null +++ b/tests/auto/language/testdata/erroneous/syntax-error-in-probe.qbs @@ -0,0 +1,8 @@ +import qbs + +Product { + Probe { + id: hurz + configure: { fngkgsdjfgklkf } + } +} diff --git a/tests/auto/language/tst_language.cpp b/tests/auto/language/tst_language.cpp index 4c52dfd74..cff601b3d 100644 --- a/tests/auto/language/tst_language.cpp +++ b/tests/auto/language/tst_language.cpp @@ -742,6 +742,8 @@ void TestLanguage::erroneousFiles_data() << "PropertyOptions item refers to non-existing property 's0meProp'"; QTest::newRow("missing-colon") << "Invalid item 'cpp.dynamicLibraries'. Did you mean to set a module property?"; + QTest::newRow("syntax-error-in-probe") + << "syntax-error-in-probe.qbs:6:20.*ReferenceError"; QTest::newRow("wrong-toplevel-item") << "wrong-toplevel-item.qbs:3:1.*The top-level item must be of type 'Project' or " "'Product', but it is of type 'Artifact'."; -- cgit v1.2.3