Estoy usando el motor de script Qt en mi aplicación como una forma alternativa para que el usuario acceda a su funcionalidad. Como tal, exporto algunas clases de C++ al Qt ScriptEngine, que servirá como interfaz para la aplicación. El problema es que estas clases de C++ pueden arrojar excepciones.Manejo de la excepción C++ lanzada en la función exportada a QtScript
Tengo una clase "ScriptInterface" ejecutándose en su propio hilo, escuchando solicitudes para procesar scripts. Entonces cuando evalúo la secuencia de comandos de un usuario, tengo un bloque try/catch alrededor para manejar las excepciones e imprimir el error en la consola de la aplicación.
...
try {
m_engine->evaluate(script, name);
}
catch (Exception const& e) {
// deal with it
}
catch (...) {
// scary message
}
Esto funciona perfectamente en Windows ... pero no funciona en linux el programa termina con este mensaje:
terminate called after throwing an instance of 'Basilisk::InvalidArgumentException'
what(): N8Basilisk24InvalidArgumentExceptionE
Aborted
tuve el presentimiento de que era debido a las excepciones burbujear hasta el controlador de eventos (dado que el motor de scripts usa señales para llamar a las funciones en mis clases exportadas), así que reimplementé QApplication :: notify, para manejar excepciones allí, pero no fueron atrapadas.
Mi pregunta es, ¿estoy haciendo algo fundamentalmente malo? Además, como alternativa, ¿es posible lanzar explícitamente excepciones de guiones dentro de mis clases de C++?
Gracias de antemano
EDIT: fijan la descripción para incluir el (...) sentencia catch.
ACTUALIZACIÓN (SOLUCIÓN): "solucioné" este problema siguiendo una estrategia similar a la que se describe en la respuesta aceptada. Aunque no he ido a la fuente de por qué las excepciones no quedan atrapadas en Linux (sospecho ahora, es que m_engine-> evalúan generar un hilo separado en Linux), pero he comenzado a usar el previsto manera de excepción lanzando en Qt Scripts, y eso es QScriptContext::throwError()
.
En los casos en que mi función sería el siguiente: (ejemplo al azar)
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);
}
ahora es la siguiente: (prestar especial atención al tipo de retorno)
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();
}
Entonces, ¿dónde puede uno lidiar con estos errores de script? Después de la llamada al QScriptEngine::evaluate()
puede verificar si hay excepciones no detectadas, con QScriptEngine::hasUncaughtException()
, obtenga el objeto de error con uncaughtException()
, ¡y ahora tiene el mensaje, el rastreo y el número de línea en el script donde ocurrió el error!
Espero que esto ayude a alguien!
¿Hay alguna función con [especificaciones de excepción] (http://www.gotw.ca/publications/mill22.htm) involucrado? –
No en ninguna parte de mis clases –
¿'catch (...) {}' atrapa esa excepción? – tibur