Как правильно уловить std и форсировать исключения
Расскажите, как правильно использовать 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:
Я также не могу понять теперь, чтобы извлечь информацию для регистрации из исключения???
Ответы
Ответ 1
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
, чтобы узнать больше об этом.
Ответ 2
вероятно, слишком поздно, чтобы ответить... но
<...snip...>
catch (const boost::exception& 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...>
Ответ 3
Как и в любом С++, применяется следующее универсальное правило:
Поймать все исключения, которые могут быть выброшены, и только если вы можете их осмысленно отреагировать.
Вы также можете поймать все другие исключения (...
) и создать сообщение журнала или что-то в этом роде, но затем вам нужно их сбросить (throw;
). Если вы ничего не можете сделать в своем коде, кроме отмены какой-либо операции, вам не нужно обрабатывать исключение. Пусть это пузырь до места, где его можно использовать осмысленно.
В вашем коде вам нужно будет разрешить хотя бы ошибки выделения памяти (std::bad_alloc
), чтобы вы могли проверить их, если это имеет смысл. Но опять же, если вы не знаете, что вы ловите, вы не можете многое сделать с тем, что поймаете.
Говорить, что ваша "программа не может потерпеть неудачу" может означать только столько. В конечном счете, если у вас есть ошибка распределения в структуре данных верхнего уровня, вы ничего не можете сделать. Лучший сценарий, который я могу себе представить, заключается в том, что ваша основная функция обрабатывает некоторые данные в цикле; в этом случае вы можете поместить универсальный блок try вокруг цикла, и в случае исключения вы просто переходите к следующему раунду. Но я бы сосчитал это как пример способности "обрабатывать исключение значимо", так что просто особый случай выше. В общем, хотя вам может понадобиться обернуть всю вашу основную функцию в блоке try, вам просто нужно согласиться с тем, что в конечном случае вы не имеете большого выбора, кроме как прервать программу.
Ответ 4
Это зависит от кода, который вы используете в блоке try. Если код в read_xml может вызывать std:: exception, вам лучше поймать std:: exception. Если вы не уверены, то не может повредить их обоих.
Ответ 5
Вы должны catch
использовать только специальные типы исключений, если вы действительно хотите сделать что-то, относящееся к этому типу. В противном случае просто используйте std::exception
. Если вы используете код, вы можете выбросить что-то другое, чем catch ...
вместо или std::exception
.
Если вы хотите обрабатывать несколько (специальных) типов исключений, чем сначала нужно обрабатывать наиболее явные.