как отловить неизвестное исключение и распечатать его - PullRequest
38 голосов
/ 19 июня 2010

У меня есть какая-то программа, и каждый раз, когда я ее запускаю, она выдает исключение, и я не знаю, как проверить, что именно она выбрасывает, поэтому мой вопрос, возможно ли перехватить исключение и напечатать его (я нашел строки, которые выдает исключение) заранее спасибо

Ответы [ 6 ]

50 голосов
/ 19 июня 2010

Если оно получено из std::exception, вы можете узнать по ссылке:

try
{
    // code that could cause exception
}
catch (const std::exception &exc)
{
    // catch anything thrown within try block that derives from std::exception
    std::cerr << exc.what();
}

Но если исключением является некоторый класс, который не является производным от std::exception, вам нужно будет заранее знать его тип (то есть, если вы поймаете std::string или some_library_exception_base).

Вы можете поймать всех:

try
{
}
catch (...)
{
}

но тогда вы ничего не можете сделать, за исключением.

18 голосов
/ 06 июля 2016

В C ++ 11 у вас есть: std :: current_exception

Пример кода с сайта:

#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>

void handle_eptr(std::exception_ptr eptr) // passing by value is ok
{
    try {
        if (eptr) {
            std::rethrow_exception(eptr);
        }
    } catch(const std::exception& e) {
        std::cout << "Caught exception \"" << e.what() << "\"\n";
    }
}

int main()
{
    std::exception_ptr eptr;
    try {
        std::string().at(1); // this generates an std::out_of_range
    } catch(...) {
        eptr = std::current_exception(); // capture
    }
    handle_eptr(eptr);
} // destructor for std::out_of_range called here, when the eptr is destructed
3 голосов
/ 28 июля 2014

Если вы используете ABI для gcc или CLANG, вы можете знать неизвестный тип исключения. Но это нестандартное решение.

Смотрите здесь https://stackoverflow.com/a/24997351/1859469

1 голос
/ 17 января 2019

Вдохновленный ответом hamaney:

#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>

int main()
{
   try
   { 
      // Your code
   }
   catch (...)
   {
      try
      {
         std::exception_ptr curr_excp;
         if (curr_excp = std::current_exception())
         {
            std::rethrow_exception(curr_excp);
         }
      }
      catch (const std::exception& e)
      {
         std::cout << e.what();
      }
   }
}
1 голос
/ 09 августа 2017

Вдохновленный Давидом Дроздом, ответ:

#include <exception>
try
{
    // The code that could throw
}
catch(...)
{
    auto expPtr = std::current_exception();

    try
    {
        if(expPtr) std::rethrow_exception(expPtr);
    }
    catch(const std::exception& e) //it would not work if you pass by value
    {
        std::cout << e.what();
    }
}
1 голос
/ 19 июня 2010

Попробуйте сначала по предложению Р. Самуэля Клатчко. Если это не поможет, есть кое-что еще, что может помочь:

a) Поместите точку останова на тип исключения (обработанный или необработанный), если ваш отладчик это поддерживает.

b) В некоторых системах компилятор генерирует вызов (недокументированной?) Функции при выполнении оператора throw. чтобы выяснить, какая функция для вашей системы, напишите простую программу hello world, которая выдает и перехватывает исключение. запустите отладчик и поместите точку останова в конструктор исключений и посмотрите, откуда она вызывается. функция вызова, вероятно, похожа на __throw (). после этого снова запустите отладчик с программой, которую вы хотите исследовать как отладчик. установите точку останова на функцию, указанную выше (__throw или что-либо еще), и запустите программу. когда выдается исключение, отладчик останавливается, и вы тут же узнаете, почему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...