where am I supposed to catch it?
Esto es exactamente por qué Qt no admite excepciones que lanzan a través de conexiones de señal/ranura. Si lo intenta, verá este mensaje:
Qt has caught an exception thrown from an event handler. Throwing exceptions from an event handler is not supported in Qt. You must reimplement QApplication::notify() and catch all exceptions there.
Como se menciona, es posible subclase QApplication y coger su excepción, pero que va a ser una forma muy molesto de manejar las cosas.
Si es posible, recomendaría reescribir el conteo de modo que no arroje.
¿Qué pasa si no se puede reescribir count()?
Por ejemplo, ¿qué ocurre si count() es parte de una función en una biblioteca de terceros que está utilizando?
No hay espacio en ninguna biblioteca oficial de Qt, así que si está utilizando una biblioteca de terceros con una ranura que arroja, probablemente sea una señal de que no es una buena biblioteca. Si desea utilizarlo de todos modos, le recomiendo que en lugar de detectarlo en QApplication::notify
, cree un adaptador.
¿Qué significa eso? Primero crea un objeto que capture tu objeto incompleto de terceros en el constructor. En él, escriba una ranura que envuelva una llamada a la ranura de lanzamiento con un bloque try/catch. Ahora, en lugar de conectarse a la ranura del objeto incompleto de terceros, conéctese a la ranura de su nuevo objeto creado.
Hacer la excepción de esta manera mantiene el código relacionado junto y evita que QApplication::notify
se llene con un grupo de bloques try/catch no relacionados si encuentra más de una de estas funciones problemáticas.
Por ejemplo:
class BadCounter {
Q_OBJECT
public slots:
void count() { throw CounterError("unable to count"); }
};
class CounterAdaptor {
Q_OBJECT
BadCounter* counter_;
public:
CounterAdaptor(BadCounter* counter) {
counter_ = counter;
}
public slots:
void count() {
try {
counter_->count();
} catch (const CounterError& e) {
std::cerr << e.what() << std::endl;
}
}
};
int main() {
BadCounter engine;
CounterAdaptor adaptor(&engine);
QThread* thread = new QThread();
connect(thread,SIGNAL(started()),&adaptor,SLOT(count()));
thread.start();
... // etc...
delete thread;
}
Qué pasa si usted quiere manejar algo que podría ser lanzado desde cualquier lugar?
El ejemplo obvio de este tipo de preocupación global es una excepción inesperada. Los errores pueden ocurrir en cualquier lugar. Sería deseable registrar tantos detalles sobre el evento como sea posible para que la causa pueda ser identificada y corregida. En este caso, sería desea volver a implementar QApplication::notify
en su propia subclase como se muestra en jichi's answer. Usar un controlador global para preocupaciones globales es bastante razonable.
tal vez debería poner el bloque try-catch en la función count(). .. – Kobe
#vBx count throws – smallB
Entonces su solución provista en la pregunta es buena – Kobe