Как правильно ловить std и повысить исключения - PullRequest
14 голосов
/ 15 ноября 2011

Скажите, пожалуйста, как правильно использовать try / catch с boost :: exception.

Это один из примеров

void Settings::init(const std::string &filename)
{
    using boost::property_tree::ptree;
    try 
    {
        read_xml(filename, pt);
    }
    catch(boost::exception const&  ex)
    {
        LOG_FATAL("Can't init settings. %s", /* here is the question */);
    }
}

Нужно ли мне тоже ловить std :: exception?Я не могу позволить своему приложению завершиться сбоем, поэтому мне просто нужно регистрировать все.

UPD: Я также не могу понять, как получить информацию для регистрации из исключения ???

Ответы [ 5 ]

12 голосов
/ 15 ноября 2011

std::exception имеет функцию-член под названием what(), которая возвращает const char*, который может объяснить, что произошло. Если вы хотите записать это (предполагая, что LOG_FATAL обертывает printf как-то), вы можете сделать:

catch(std::exception const&  ex)
{
    LOG_FATAL("Can't init settings. %s", ex.what());
}

Для boost::exception, хотя вы можете использовать boost::get_error_info, чтобы узнать больше об этом.

6 голосов
/ 27 февраля 2016

, вероятно, слишком поздно, чтобы ответить ... но

        <...snip...>
        catch (const boost::exception const& e)
        {
            std::string diag = diagnostic_information(e);
            // display your error message here, then do whatever you need to, e.g.        
            LOG_FATAL("Can't init settings. %s", diag);
        }
        <...snip...>
5 голосов
/ 15 ноября 2011

Как и в любом C ++, применяется следующее универсальное правило:

Поймать все исключения, которые могут быть выданы, и только , если , вы можете ответить на них осмысленно.

Вы можете также перехватить все другие исключения (...) и создать сообщение в журнале или что-то в этом роде, но затем вам придется сбросить их (throw;). Если в вашем коде вы ничего не можете сделать, кроме как прервать какую-либо операцию, вам не нужно обрабатывать исключение. Пусть он пузырится до места, где он может использоваться осмысленно.

В вашем коде вы должны будете разрешить хотя бы ошибки распределения памяти (std::bad_alloc), чтобы вы могли проверить их, если это имеет смысл. Но опять же, если вы не знаете, что ловите, мало что можно сделать с тем, что вы ловите.

Сказать, что ваша «программа не может потерпеть неудачу», может значить только очень много. В конечном счете, если у вас есть ошибка выделения в структуре данных верхнего уровня, вы ничего не можете сделать . Лучший сценарий, который я могу себе представить, - это если ваша основная функция обрабатывает некоторые данные в цикле; в этом случае вы можете поместить универсальный блок try вокруг цикла, а в случае исключения вы просто переходите к следующему раунду. Но я бы посчитал это примером того, как можно «осмысленно обработать исключение», так что это всего лишь частный случай вышеизложенного. В общем, хотя вы можете захотеть обернуть всю свою основную функцию в блок try, вы просто должны будете принять, что в конечном общем случае у вас нет большого выбора, кроме как прервать программу.

1 голос
/ 15 ноября 2011

Это зависит от кода, который вы запускаете в блоке try.Если код в read_xml может выдать исключение std :: exception, то вам также лучше перехватить std :: exception.Если вы не уверены, то поймать их обоих не помешает.

0 голосов
/ 15 ноября 2011

Вы должны catch только специальные типы исключений, если вы действительно хотите сделать что-то связанное с этим типом.В противном случае просто используйте std::exception.Если ваш код может выдать что-то иное, чем перехватывать ... вместо или после std::exception.

Если вы хотите обрабатывать несколько (специальных) типов исключений, чем сначала нужно обработать наиболее явное.

...