Я использую механизм сценариев Qt в своем приложении как альтернативный способ доступа пользователя к его функциям. Таким образом, я экспортирую некоторые классы C++ в Qt ScriptEngine, который будет служить интерфейсом для приложения. Проблема в том, что эти классы C++ могут генерировать исключения.Обработка исключений C++, брошенных в функцию, экспортированных в QtScript
У меня есть класс ScriptInterface, запущенный в своем потоке, прислушиваясь к запросам на обработку скриптов. Поэтому, когда я оцениваю скрипт пользователя, у меня есть блок try/catch, который обрабатывает исключения, и печатает ошибку на консоли в приложении.
...
try {
m_engine->evaluate(script, name);
}
catch (Exception const& e) {
// deal with it
}
catch (...) {
// scary message
}
Это отлично работает в окнах ... но не работает в linux- программы завершается с этим сообщением:
terminate called after throwing an instance of 'Basilisk::InvalidArgumentException'
what(): N8Basilisk24InvalidArgumentExceptionE
Aborted
Я догадывался, что это было из-за исключения ых до обработчик события (поскольку механизм сценария использует сигналы для вызова функций в моих экспортированных классах), поэтому я переопределял QApplication :: notify, чтобы обрабатывать исключения там, но они не были пойманы.
Мой вопрос: я делаю что-то принципиально неправильно? Кроме того, в качестве альтернативы можно ли явно передать исключения скриптов из моих классов C++?
Заранее спасибо
EDIT: исправили описание включить улов (...) заявление.
ОБНОВЛЕНИЕ (РЕШЕНИЕ): Я «исправил» эту проблему, следуя стратегии, аналогичной той, которая описана в принятом ответе. Хотя я не пришел к источнику того, почему исключения не попадают в linux (теперь я подозреваю, что m_engine-> оценивает порождение отдельного потока на linux), но я начал использовать , предназначенный для. исключение бросается в Qt Scripts, и это QScriptContext::throwError()
.
В тех случаях, когда моя функция будет выглядеть следующим образом: (случайный пример)
void SomeClass::doStuff(unsigned int argument) {
if (argument != 42) {
throw InvalidArgumentException(
"Not the answer to Life, the Universe and Everything.");
}
// function that is not part of the scripting environment,
// and can throw a C++ exception
dangerousFunction(argument);
}
Теперь это: (обратить особое внимание на тип возвращаемого)
QScriptValue SomeClass::doStuff(unsigned int argument) {
if (argument != 42) {
// assuming m_engine points to an instance of
// QScriptEngine that will be calling this function
return m_engine->currentContext()->throwError(QScriptContext::SyntaxError,
"Not the answer to Life, the Universe and Everything.");
}
try {
// function that is not part of the scripting environment,
// and can throw a C++ exception
dangerousFunction(argument);
} catch (ExpectedException const& e) {
return m_engine->currentContext()->throwError(QScriptContext::UnknownError,
e.message());
}
// if no errors returned, return an invalid QScriptValue,
// equivalent to void
return QScriptValue();
}
Так где же один справиться с этими ошибками скрипта? После вызова QScriptEngine::evaluate()
вы можете проверить, есть ли какие-либо неперехваченные исключения, с QScriptEngine::hasUncaughtException()
, получить объект ошибки с uncaughtException()
, и теперь у вас есть сообщение, трассировка и номер строки в скрипте, где произошла ошибка!
Надеюсь, что это поможет кому-то!
Есть ли функция с [спецификациями исключения] (http://www.gotw.ca/publications/mill22.htm)? –
Не где-нибудь в моих классах –
Does catch (...) {} 'catch this exception? – tibur