Suppose there is a class for working with the database. There are methods of this class that handle possible errors through if, writing the text of the error that occurred to the lastError class variable, sending a signal that an error has occurred and returning what the method should return in case of an error.

bool insertIntoSomeTable() { // Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ…ΠΎΠ΄ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ if( ошибка ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ) { lastError=ошибка ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ; emit errorHasOccured(lastError); return false; } // Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ…ΠΎΠ΄ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ if( сСрвСр Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅) { lastError=сСрвСр Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅; emit errorHasOccured(lastError); return false; } // Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ…ΠΎΠ΄ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ if( ошибка выполСния запроса ) { lastError=ошибка выполСния запроса; emit errorHasOccured(lastError); return false; } //ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅ return true } 

As a result, these ifs are very cluttered with method code. Is it normal practice if I redefine my exception class for the database and rewrite the method like this:

  bool insertIntoSomeTable() { try { // Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ…ΠΎΠ΄ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ if( ошибка ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ) { throw DatabaseException("Ошибка ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ"); } // Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ…ΠΎΠ΄ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ if( сСрвСр Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅) { throw DatabaseException("сСрвСр Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅"); } // Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ…ΠΎΠ΄ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ if( ошибка выполСния запроса ) { throw DatabaseException("ошибка выполСния запроса"); } //ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅ return true } catch(DatabaseException& e) { lastError= e.what(); emit errorHasOccured(lastError); return false; } } 

Also, of course, you can make this method void; in the method itself, do only throw, and catch errors somewhere higher. But I would not really like to do that. In general, is it ok to use the above option?

    1 answer 1

    Is it normal practice if I redefine my exception class for the database and rewrite the method like this

    Will be normal.

    Example of "wrong" ifs

     bool Func1() { if (err) return false; return true; } bool Func2() { if (err) return false; return true; } bool Func3() { if (err) return false; return true; } // ... int MainFunc() { if (!Func1()) return -1; if (!Func2()) return -2; if (!Func3()) return -3; } 

    In this example above, there is an explicit double check. First on the action, then on the return code. That's not necessary. It is for such a case, or rather - and including, that they invented exception handling.

    It would be right

     void Func1() { if (err) throw myexception(1); } void Func2() { if (err) throw myexception(2); } void Func3() { if (err) throw myexception(3); } // ... int MainFunc() { try { Func1(); Func2(); Func3(); } catch(myexception &e) { // some } catch(...) { // some } } 

    But, if in your code "check-not-check" - write so as to eliminate verbosity. In general, we read Occam's Razor )

    • thank. still a small question. inherited its exception class from std :: exception (class DbException: std :: exception). But, for some reason, exceptions from it are caught only if catching catch (DbException & e) explicitly, and if catching from a base catch (std :: exception & e), then it does not intercept it and everything ends with std :: terminate. Why? - bronstein87
    • Create a separate question and give your code, otherwise you just have to guess - Majestio