From 7f0db6d0472037a3ec005f9066f6222d78de60e1 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 1 Aug 2017 16:31:53 +0200 Subject: Add convenience functions for creating and inspecting error objects Serves to simplify porting from QtScript by replacing QScriptContext::Error and QScriptContext::throwError(). Change-Id: I4bfe404c358c50aaf3b5469a4304fec97552bf24 Reviewed-by: Paul Wicking Reviewed-by: Simon Hausmann --- src/qml/jsapi/qjsengine.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++ src/qml/jsapi/qjsengine.h | 3 ++ src/qml/jsapi/qjsvalue.cpp | 53 ++++++++++++++++++++++++++++++++- src/qml/jsapi/qjsvalue.h | 12 ++++++++ 4 files changed, 139 insertions(+), 1 deletion(-) (limited to 'src/qml/jsapi') diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 69e1436c0a..3bde6a60c4 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -45,6 +45,7 @@ #include "private/qv4engine_p.h" #include "private/qv4mm_p.h" +#include "private/qv4errorobject_p.h" #include "private/qv4globalobject_p.h" #include "private/qv4script_p.h" #include "private/qv4runtime_p.h" @@ -582,6 +583,46 @@ QJSValue QJSEngine::newObject() return QJSValue(m_v4Engine, v->asReturnedValue()); } +/*! + \since 5.12 + Creates a JavaScript object of class Error. + + The prototype of the created object will be \a errorType. + + \sa newObject(), throwError(), QJSValue::isError() +*/ +QJSValue QJSEngine::newErrorObject(QJSValue::ErrorType errorType, const QString &message) +{ + QV4::Scope scope(m_v4Engine); + QV4::ScopedObject error(scope); + switch (errorType) { + case QJSValue::RangeError: + error = m_v4Engine->newRangeErrorObject(message); + break; + case QJSValue::SyntaxError: + error = m_v4Engine->newSyntaxErrorObject(message); + break; + case QJSValue::TypeError: + error = m_v4Engine->newTypeErrorObject(message); + break; + case QJSValue::URIError: + error = m_v4Engine->newURIErrorObject(message); + break; + case QJSValue::ReferenceError: + error = m_v4Engine->newReferenceErrorObject(message); + break; + case QJSValue::EvalError: + error = m_v4Engine->newEvalErrorObject(message); + break; + case QJSValue::GenericError: + error = m_v4Engine->newErrorObject(message); + break; + case QJSValue::NoError: + return QJSValue::UndefinedValue; + } + return QJSValue(m_v4Engine, error->asReturnedValue()); +} + /*! Creates a JavaScript object of class Array with the given \a length. @@ -894,6 +935,37 @@ void QJSEngine::throwError(const QString &message) m_v4Engine->throwError(message); } +/*! + Throws a run-time error (exception) with the given \a errorType and + \a message. + + \code + // Assuming that DataEntry is a QObject-derived class that has been + // registered as a singleton type and provides an invokable method + // setAge(). + + void DataEntry::setAge(int age) { + if (age < 0 || age > 200) { + jsEngine->throwError(QJSValue::RangeError, + "Age must be between 0 and 200"); + } + ... + } + \endcode + + \since Qt 5.12 + \sa {Script Exceptions}, newErrorObject() +*/ +void QJSEngine::throwError(QJSValue::ErrorType errorType, const QString &message) +{ + QV4::Scope scope(m_v4Engine); + QJSValue error = newErrorObject(errorType, message); + QV4::ScopedObject e(scope, QJSValuePrivate::getValue(&error)); + if (!e) + return; + m_v4Engine->throwError(e); +} + QJSEnginePrivate *QJSEnginePrivate::get(QV4::ExecutionEngine *e) { return e->jsEngine()->d_func(); diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h index 5c8613ffd6..6300842341 100644 --- a/src/qml/jsapi/qjsengine.h +++ b/src/qml/jsapi/qjsengine.h @@ -84,6 +84,8 @@ public: return newQMetaObject(&T::staticMetaObject); } + QJSValue newErrorObject(QJSValue::ErrorType errorType, const QString &message = QString()); + template inline QJSValue toScriptValue(const T &value) { @@ -114,6 +116,7 @@ public: QV4::ExecutionEngine *handle() const { return m_v4Engine; } void throwError(const QString &message); + void throwError(QJSValue::ErrorType errorType, const QString &message = QString()); private: QJSValue create(int type, const void *ptr); diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 9671e82187..14baf0ac10 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -159,6 +159,22 @@ This is a typedef for a QList. */ +/*! + \enum QJSValue::ErrorType + \since 5.12 + + This enum is used to specify a type of Error object. + + \value NoError Not an Error object. + \value GenericError A generic Error object, but not of a specific sub-type. + \value EvalError An error regarding the global eval() function. + \value RangeError A value did not match the expected set or range. + \value ReferenceError A non-existing variable referenced. + \value SyntaxError Invalid syntax. + \value TypeError A value did not match the expected type. + \value URIError A URI handling function was used incorrectly. +*/ + QT_BEGIN_NAMESPACE using namespace QV4; @@ -371,7 +387,7 @@ bool QJSValue::isUndefined() const Returns true if this QJSValue is an object of the Error class; otherwise returns false. - \sa {QJSEngine#Script Exceptions}{QJSEngine - Script Exceptions} + \sa errorType(), {QJSEngine#Script Exceptions}{QJSEngine - Script Exceptions} */ bool QJSValue::isError() const { @@ -381,6 +397,41 @@ bool QJSValue::isError() const return val->as(); } +/*! + \since 5.12 + Returns the error type this QJSValue represents if it is an Error object. + Otherwise, returns \c NoError." + + \sa isError(), {QJSEngine#Script Exceptions}{QJSEngine - Script Exceptions} +*/ +QJSValue::ErrorType QJSValue::errorType() const +{ + QV4::Value *val = QJSValuePrivate::getValue(this); + if (!val) + return NoError; + QV4::ErrorObject *error = val->as(); + if (!error) + return NoError; + switch (error->d()->errorType) { + case QV4::Heap::ErrorObject::Error: + return GenericError; + case QV4::Heap::ErrorObject::EvalError: + return EvalError; + case QV4::Heap::ErrorObject::RangeError: + return RangeError; + case QV4::Heap::ErrorObject::ReferenceError: + return ReferenceError; + case QV4::Heap::ErrorObject::SyntaxError: + return SyntaxError; + case QV4::Heap::ErrorObject::TypeError: + return TypeError; + case QV4::Heap::ErrorObject::URIError: + return URIError; + } + Q_UNREACHABLE(); + return NoError; +} + /*! Returns true if this QJSValue is an object of the Array class; otherwise returns false. diff --git a/src/qml/jsapi/qjsvalue.h b/src/qml/jsapi/qjsvalue.h index 56bd64eec1..2f95e0ff31 100644 --- a/src/qml/jsapi/qjsvalue.h +++ b/src/qml/jsapi/qjsvalue.h @@ -68,6 +68,17 @@ public: UndefinedValue }; + enum ErrorType { + NoError, + GenericError, + EvalError, + RangeError, + ReferenceError, + SyntaxError, + TypeError, + URIError + }; + public: QJSValue(SpecialValue value = UndefinedValue); ~QJSValue(); @@ -137,6 +148,7 @@ public: QJSValue callWithInstance(const QJSValue &instance, const QJSValueList &args = QJSValueList()); // ### Qt6: Make const QJSValue callAsConstructor(const QJSValueList &args = QJSValueList()); // ### Qt6: Make const + ErrorType errorType() const; #ifdef QT_DEPRECATED QT_DEPRECATED QJSEngine *engine() const; #endif -- cgit v1.2.3