Exceptions Behandlung in Qt



  • Hallo zusammen, ich hoffe das es das richtige Forum ist für diese Frage...

    zurzeit arbeite ich gerade an einem Qt Projekt und bin sehr begeistert von diesem Framework.

    Heute aber bin ich auf ein Problem mit Exceptions gestoßen, welches ich bisher nicht lösen konnte.

    Werfe ich z.B. im Konstruktor einer Klasse eine exception, so stürzt mein Program ab, mit der Meldung "...Runtime Error...Program terminated".

    Beim recherchieren im Internet, geben viele die Empfehlung (auch Qt-Entwickler) Exceptions nicht zu verwenden.

    Eine weitere Vermutung von mir ist, das es evtl. mit den Threads von Qt zu tun hat...

    Also meine Frage an euch: Wie macht ihr das?



  • Dein Problem hat nichts mit Qt zu tun. Wenn du eine Exception nicht fängst, wird das Programm beendet. Irgendwo muss der Fehler halt registriert und behandelt wrden.

    Was dabei raus kommt, wenn man keine Exceptions sondern Returncodes verwendet, sieht man sehr schön beim gotofail bei Apple (wobei natürlich in reinem C-Code keine Exceptions verwendet werden können).



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum Andere GUIs - Qt, GTK+, wxWidgets verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • du hast recht, ohne catch block wird die Fehlermeldung an das OS weitergereicht...in diesem Fall habe ich aber eine und trotzdem stürzt das Program ab..

    try {
       ....
    } catch (std::string &msg) {
       std::cerr << "Fehler: " << msg << std::endl;
    }
    


  • Ist der catch auch richtig? Wär das so schwer gewesen, gleich das throw auch mitzuposten?



  • DKlay schrieb:

    ...in diesem Fall habe ich aber eine und trotzdem stürzt das Program ab..

    try {
       ....
    } catch (std::string &msg) {
       std::cerr << "Fehler: " << msg << std::endl;
    }
    

    Der catch ist auch in dem Thread, in dem die Exception geworfen wird?



  • manni66 schrieb:

    DKlay schrieb:

    ...in diesem Fall habe ich aber eine und trotzdem stürzt das Program ab..

    try {
       ....
    } catch (std::string &msg) {
       std::cerr << "Fehler: " << msg << std::endl;
    }
    

    Der catch ist auch in dem Thread, in dem die Exception geworfen wird?

    Das ist eine gute Frage, also es ist aufjedenfall kein Thread den ich erzeuge, wenn dann transparent von Qt.

    Aus meinem MainWindow, erstelle ich in Methode die über eine QAction aufgerufen wird. Innerhalb der Methode erzeuge ich eine Instanz meiner Klasse, die versucht eine Verbindung zum SQL-Server aufzubauen...sollte es Probleme geben mit dem Verbindungsaufbau, so werfe ich eine Exception vom Typ std::string.

    Mechanics schrieb:

    Ist der catch auch richtig? Wär das so schwer gewesen, gleich das throw auch mitzuposten?

    throw std::string("ein fehler");
    


  • Also irgendwie willst du wohl gar keine Hilfe, oder warum muss man dir jedes Semikolon einzeln aus der Nase ziehen?
    Die Funktion wird dann ja wohl über die Eventloop ausgeführt. Wo steht das try catch? Doch wohl in der Funktion? Wenn nein: was stellst du dir vor, was passieren soll, wenn man eine Exeption durch die Eventloop ballert?



  • manni66 schrieb:

    Also irgendwie willst du wohl gar keine Hilfe, oder warum muss man dir jedes Semikolon einzeln aus der Nase ziehen?
    Die Funktion wird dann ja wohl über die Eventloop ausgeführt. Wo steht das try catch? Doch wohl in der Funktion? Wenn nein: was stellst du dir vor, was passieren soll, wenn man eine Exeption durch die Eventloop ballert?

    Den Code hatte ich nicht zur Verfügung... 😕
    Wie auch immer, hier wenn das weiter hilft.

    void MainWindow::search()
    {
    
        SQL *test = new SQL();
        MYSQL *ptrCon;
        try {
            if(!test->getSQLInstance(ptrCon)) {
                QMessageBox::critical(this, "Fehler", test->getErrorMsg().c_str());
            }
            else {
                SearchDlg *search = new SearchDlg(ptrCon);
                search->setModal(true);
                search->setFixedHeight( search->height() );
                search->setFixedWidth( search->width() );
                search->show();
            }
        } catch(std::string &msg) {
            std::cout << msg << std::endl;
        }
    }
    
    bool SQL::getSQLInstance(MYSQL *sql)
    {
        if(!con) 
        {
            con = mysql_init(nullptr);
    
            if(con == nullptr) { // Initialisierung fehlgeschlagen
                throw std::string(mysql_error(con));
            }
            else 
            {
                LoginDlg *login = new LoginDlg();
    
                if(login->exec() == QDialog::Accepted) 
                {
                    if (mysql_real_connect(con, hostname.c_str(), login->getUsername().c_str(), login->getPassword().c_str(), NULL, 0, NULL, 0) == NULL) 
                    {
                        throw std::string(mysql_error(con));
                    } 
                    else {
                        char statement[50];
                        sprintf(statement, "use %s", database.c_str());
    
                        if(mysql_query(con, statement)) { // Ist bei der Verwendung der Datenbank ein Fehler aufgetreten?
                            throw std::string(mysql_error(con));
                        } else {
                            sql = con;
                            return true;
                        }
                    }
                }
    
                mysql_close(con);
                con = nullptr;
                return false;
            }
        }
    
        sql = con;
        return true;
    }
    

  • Mod

    Es ist eher unüblich std::string & co als exception zu werfen, std::runtime_error wäre evtl. eine gute Alternative.
    Evtl. wird deine Exception auch nicht gefangen weil sie const std::string& ist. Ich habe aber noch nie einen String geworfen, von daher kann ich dir gar nicht sagen, wie du das fangen solltest.

    Und warum nimmst du nicht die DB Klassen von Qt? Qt kann auch auf MySQL zugreifen!



  • Ich sehe keinen Konstruktor, der eine Exception wirft.
    Welchen Sinn hat Zeile 39?
    login erzeugt ein Speicherleck!
    sprintf in einen Puffer - warum?



  • manni66 schrieb:

    Ich sehe keinen Konstruktor, der eine Exception wirft.
    Welchen Sinn hat Zeile 39?
    login erzeugt ein Speicherleck!
    sprintf in einen Puffer - warum?

    Danke für den Hinweis mit dem Speicherleck, habe es beim suchen des Problems übersehen. Das mit dem Konstruktor war wohl eine Fehlinformationen von mir...wie gesagt hatte den Code nicht zur Verfügung gestern Abend!

    Zur Zeile 39:
    Es wird dem übergebenen MYSQL *sql, die initialisierte MYSQL* Verbindung zugewiesen, wenn alles geklappt hat. Diesen möchte ich wenn gültig Global in der Anwendung nutzen. Und "con" ist eine statische Variable vom Typ MYSQL*.

    Was hat das mit der Exception zutun?



  • DKlay schrieb:

    Das mit dem Konstruktor war wohl eine Fehlinformationen von mir...wie gesagt hatte den Code nicht zur Verfügung gestern Abend!

    Du redest also einen Haufen dummes Zeug, lässt dir jedes Details aus der Nase ziehen, zeigst nicht die allergeringste Initiative hier weiter zukommen und erwartest ernsthaft, dass dir jemand hilft?

    DKlay schrieb:

    Zur Zeile 39:
    Es wird dem übergebenen MYSQL *sql, die initialisierte MYSQL* Verbindung zugewiesen, wenn alles geklappt hat. Diesen möchte ich wenn gültig Global in der Anwendung nutzen. Und "con" ist eine statische Variable vom Typ MYSQL*.

    Dann rate mal, wie lange sql nach dieser Zeile noch existiert.

    DKlay schrieb:

    Was hat das mit der Exception zutun?

    Ich glaube nicht, dass eine geworfen wird, insbesondere da du ja nicht in der Lage oder Willens bist, eine entsprechende Stelle zu benennen!



  • manni66 schrieb:

    DKlay schrieb:

    Das mit dem Konstruktor war wohl eine Fehlinformationen von mir...wie gesagt hatte den Code nicht zur Verfügung gestern Abend!

    Du redest also einen Haufen dummes Zeug, lässt dir jedes Details aus der Nase ziehen, zeigst nicht die allergeringste Initiative hier weiter zukommen und erwartest ernsthaft, dass dir jemand hilft?

    manni66 ich suche konstruktive Ratschläge, keine 0815 Antworten.

    Wenn du ihn Quellcode keine siehst, dann hast du evtl. keine Ahnung was Excepitions sind oder du willst nicht helfen.

    Wenn ich es hier aber denoch falsch machen sollte, was ja der Fall ist bei runtime error, dann will ich wissen wie es "erfahrene Qt" Entwickler mit der Behandlung von Exceptions machen. Wüsste ich es besser, dann hätte ich die Frage nicht gestellt.

    Kindergarten?!



  • Ist Exception Handling in den Projekteinstellungen überhaupt aktiviert?

    Du verwendest zu viele Heapobjekte und löscht sie nicht. Die meisten davon könnte man wenn ich das richtig sehe auch einfach auf dem Stack anlegen.

    Ich seh da jetzt erstmal nichts Qt spezifisches an der Frage. Ob man Exceptions verwendet oder nicht ist mehr oder weniger Geschmackssache, bzw. da gabs auch mehrere Diskussionen zu dem Thema hier im Forum. Wie du Exceptions verwendest hat jetzt wenig mit Qt zu tun. Du hast einfach eine Funktion, die Exceptions schmeißt und die fängst du mit try catch, das ist alles normales C++.
    Wir verwenden in der Arbeit nur sporadisch Exceptions, verwenden sie aber auch. Funktioniert an sich problemlos.


Log in to reply