Подтвердить что ты не робот

С++ получает описание исключения, пойманного в catch (...) block

Могу ли я получить описание исключения, пойманного

catch(...)

блок? что-то вроде .what() из std:: exception.

4b9b3361

Ответ 1

Существует один трюк, который вы могли бы использовать:

catch(...) {
    handle_exception();
}

void handle_exception() {
    try {
        throw;
    } catch (const std::exception &e) {
        std::cout << e.what() << "\n";
    } catch (const int i) {
        std::cout << i << "\n";
    } catch (const long l) {
        std::cout << l << "\n";
    } catch (const char *p) {
        std::cout << p << "\n";
    } catch (...) {
        std::cout << "nope, sorry, I really have no clue what that is\n";
    }

и т.д., поскольку столько разных типов, сколько вы думаете, может быть выброшено. Если вы действительно ничего не знаете о том, что может быть выбрано, то даже этот второй-последний неверен, потому что кто-то может выбросить char*, который не указывает на строку с нулевым завершением.

Как правило, плохая идея бросать все, что не является std::exception или производным классом. Причина std::exception заключается в том, чтобы разрешить всем бросать и ловить объекты, с которыми они могут делать что-то полезное. В игрушечной программе, где вы просто хотите выбраться оттуда, и даже не можете быть обеспокоены включением стандартного заголовка, хорошо, возможно, выпустите int или строковый литерал. Я не думаю, что сделаю эту часть формального интерфейса. Любые исключения, которые вы бросаете, являются частью вашего формального интерфейса, даже если вы как-то забыли их документировать.

Ответ 2

Этот блок может поймать int или const char * или что угодно. Как компилятор может знать, как описать что-то, когда он ничего не знает об этом? Если вы хотите получить информацию от исключения, вы должны знать тип.

Ответ 3

Если вы знаете, что выбрали только std:: exception или subclasses, попробуйте

catch(std::exception& e) {...e.what()... }

В противном случае, как писал DeadMG, поскольку вы можете полностью (почти) все, вы не можете предположить ничего о том, что вы поймали.

Обычно catch (...) следует использовать только в качестве последней защиты при использовании плохо написанных или задокументированных внешних библиотек. Таким образом, вы использовали бы иерархию

catch(my::specialException& e) {
      // I know what happened and can handle it
      ... handle special case
      }
catch(my::otherSpecialException& e) {
      // I know what happened and can handle it
      ... handle other special case
      }
catch(std::exception& e) {
      //I can at least do something with it
      logger.out(e.what());
      }
catch(...) {
     // something happened that should not have 
     logger.out("oops");
     }

Ответ 4

Так как С++ 11 вы можете захватить текущее исключение указателем:

std::exception_ptr p;     // default initialization is to nullptr

try {
      throw 7;
}
catch(...)
{
     p = std::current_exception();
}

Это ведет себя как умный указатель; пока есть хотя бы один указатель, указывающий на объект исключения, он не будет уничтожен.

Позже (возможно, даже в другой функции) вы можете предпринять действия аналогично текущему верхнему ответу:

try {
    if ( p )
        std::rethrow_exception(p);
}
catch(int x)
{

}
catch(std::exception &y)
{
}

Ответ 5

Как мы реализовали наши исключения, мы имеем собственные классы исключения, все из которых получены из std::exception..

Наши исключения будут содержать сообщение об исключении, имя функции, имя файла и строку, где генерируются исключения. Все они полезны не только для показа сообщений, но также могут использоваться для ведения журнала, что помогает легко диагностировать исключение. Итак, мы получаем всю информацию об генерируемых исключениях.

Запомните исключения для us, чтобы получить информацию о том, что пошло не так. Таким образом, каждый бит информации помогает в этом отношении.

Ответ 6

Цитата bobah

#include <iostream>

#include <exception>
#include <typeinfo>
#include <stdexcept>

int main()
{
    try {
        throw ...; // throw something
    }
    catch(...)
    {
        std::exception_ptr p = std::current_exception();
        std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
    }
    return 1;
}