подход к try-catch
От: Аноним  
Дата: 05.10.05 10:44
Оценка:
Народ, подскажите что можно использовать в случае если во многих методах класса стоит банальный список try-catch блоков, причем catch блоки повторяются. Каким образом можно избавиться от повторяющихся catch блоков, желательно без использования макросов?
Re: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 12:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>причем catch блоки повторяются. Каким образом можно избавиться от повторяющихся catch блоков, желательно без использования макросов?


Для catch-ей макросы рулят Мои мысли здесь
Автор: Коваленко Дмитрий
Дата: 19.02.03
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: подход к try-catch
От: Conr Россия  
Дата: 05.10.05 12:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Народ, подскажите что можно использовать в случае если во многих методах класса стоит банальный список try-catch блоков, причем catch блоки повторяются. Каким образом можно избавиться от повторяющихся catch блоков, желательно без использования макросов?

Если код свой, то проще всего все исключения наследовать от какого-нибудь базового класса, например std::exception. А вот если это невозможно (много переделывать и тд), то имхо макрос вполне уместен...
Re: подход к try-catch
От: 0xDEADBEEF Ниоткуда  
Дата: 05.10.05 14:39
Оценка: 496 (54)
Hello, Аноним !
You wrote on Wed, 05 Oct 2005 10:44:31 GMT:

А> Каким образом можно избавиться от повторяющихся catch

А> блоков, желательно без использования макросов?
Используем "фильтр исключений" (вот так):
void TheFunction()
{
    try {
        //твоя функция
    } catch(...) {
        ExceptionFilter();
    }
}

void ExceptionFilter()
{
    try {
        throw;
    } catch(Exception1 const& e) {
        //делаем одно
    } catch(Exception2 const& e) {
        //делаем второе
    } catch(Exception3 const& e) {
        //делаем третье
    } catch(Exception4 const& e) {
        //делаем четвертое
    } catch(Exception5 const& e) {
        //делаем пятое
    } catch(...) {
        //делаем еще что-то
    }
}


ЗЫ. Естественно, фильтров и их вариаций может быть много...
Posted via RSDN NNTP Server 2.0 beta
__________
16.There is no cause so right that one cannot find a fool following it.
Re[2]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 14:42
Оценка: +1 :)
Здравствуйте, 0xDEADBEEF, Вы писали:

А>> Каким образом можно избавиться от повторяющихся catch

А>> блоков, желательно без использования макросов?
DEA>Используем "фильтр исключений" (вот так):

Убийца!

DEA>ЗЫ. Естественно, фильтров и их вариаций может быть много...


-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: подход к try-catch
От: 0xDEADBEEF Ниоткуда  
Дата: 05.10.05 15:39
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

DEA>>Используем "фильтр исключений" (вот так):

КД>Убийца!
Да не расстраивайся ты. Вот подожду чуток (пока рейтинг подрастет) и поставлю тебе троечку
__________
16.There is no cause so right that one cannot find a fool following it.
Re[2]: подход к try-catch
От: Кодт Россия  
Дата: 05.10.05 16:29
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

Офигеть.
Интересно, это законное поведение или хак вокруг типичной реализации механизма бросания?
Перекуём баги на фичи!
Re[4]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 16:30
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>>>Используем "фильтр исключений" (вот так):

КД>>Убийца!
DEA>Да не расстраивайся ты. Вот подожду чуток (пока рейтинг подрастет) и поставлю тебе троечку

Спасибо Ехал домой и думал "Боже, прошел уже час от пережитого потрясения, а я все еще живой!"

Нет, правда — в моей башке произошел прорыв. Хотя моя память мне подсказывает, что я такой финт с throw тоже проделывал — но не в таком контексте.

Красиво
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: подход к try-catch
От: 0xDEADBEEF Ниоткуда  
Дата: 05.10.05 16:37
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 0xDEADBEEF, Вы писали:


К>Офигеть.

К>Интересно, это законное поведение или хак вокруг типичной реализации механизма бросания?
Я этот метод применил как-то случайно... Сработало.
Покурил стандарт и не нашел ничего чтобы противоречило такому подходу.
Протестил — VC 6.0+, ШСД 8.1, GCC 3.2+, aCC (hp-ux) не ругаются...
__________
16.There is no cause so right that one cannot find a fool following it.
Re[3]: подход к try-catch
От: Centaur Россия  
Дата: 05.10.05 16:40
Оценка: 30 (3)
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, 0xDEADBEEF, Вы писали:


К>Офигеть.

К>Интересно, это законное поведение или хак вокруг типичной реализации механизма бросания?

15.1/7: The exception thrown is the one most recently caught and not finished. An exception is considered caught when initialization is complete for the formal parameter of the corresponding catch clause, or when terminate() or unexpected() is entered due to a throw. An exception is considered finished when the corresponding catch clause exits or when unexpected() exits after being entered due to a throw.

15.1/8: If no exception is presently being handled, executing a throw-expression with no operand calls terminate() (15.5.1).


Ничего не говорится про то, что throw обязано находиться непосредственно в catch-обработчике Собственно, если бы это требовалось, то пункт 15.1/8 бы был избыточным. Следовательно, перебрасывать исключение из отдельной функции — легально. И даже вызывать такую функцию, когда нет исключения, тоже легально — поведение полностью определено
Re[2]: подход к try-catch
От: aton Россия http://ruby.inuse.ru
Дата: 05.10.05 16:54
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Hello, Аноним !

DEA>You wrote on Wed, 05 Oct 2005 10:44:31 GMT:

А>> Каким образом можно избавиться от повторяющихся catch

А>> блоков, желательно без использования макросов?
DEA>Используем "фильтр исключений" (вот так):
DEA>
DEA>void TheFunction()
DEA>{
DEA>    try {
DEA>        //твоя функция
DEA>    } catch(...) {
DEA>        ExceptionFilter();
DEA>    }
DEA>}

DEA>void ExceptionFilter()
DEA>{
DEA>    try {
DEA>        throw;
DEA>    } catch(Exception1 const& e) {
DEA>        //делаем одно
DEA>    } catch(Exception2 const& e) {
DEA>        //делаем второе
DEA>    } catch(Exception3 const& e) {
DEA>        //делаем третье
DEA>    } catch(Exception4 const& e) {
DEA>        //делаем четвертое
DEA>    } catch(Exception5 const& e) {
DEA>        //делаем пятое
DEA>    } catch(...) {
DEA>        //делаем еще что-то
DEA>    }
DEA>}
DEA>


DEA>ЗЫ. Естественно, фильтров и их вариаций может быть много...


как правило для каждой функции/метода своя особенная обработка исключении, а это означает что таких фильтров
будет либо очень много, либо их логика будет слишком запутанной. К тому же из ExceptionFilter достаточно проблематично
повторно вызвать функцию/метод кидающую исключение. Мне кажется такой подход пригоден лишь для обобшения процедуры
фиксирования исключений, но ни как для их обработки, и то в тех случаях когда Exception1 не унаследован от некоторого
базового класса...
Re[3]: подход к try-catch
От: 0xDEADBEEF Ниоткуда  
Дата: 05.10.05 17:12
Оценка: :)
Здравствуйте, aton, Вы писали:

DEA>>ЗЫ. Естественно, фильтров и их вариаций может быть много...


A>как правило для каждой функции/метода своя особенная обработка исключении,

A>а это означает что таких фильтров будет либо очень много, либо их логика будет слишком запутанной.
...Эта штука может реально пригодиться (я ее так испоьзую) для трансляции "чужих" исключений в исключения базирующиеся на "std::exception" и дальнейшего их rethrow-а. Дело в том, что часто приходится использовать "старые" библиотеки, которые еще не слышали о std::exception и поэтому бросаются всякой фигней вместо нормальных исключений.


A>К тому же из ExceptionFilter достаточно проблематично повторно вызвать функцию/метод кидающую исключение.

Повторно??? А зачем? Чтобы еще раз получить исключение?

A>Мне кажется такой подход пригоден лишь для обобшения процедуры фиксирования исключений,

+1
__________
16.There is no cause so right that one cannot find a fool following it.
Re[3]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 17:18
Оценка:
Здравствуйте, aton, Вы писали:

A>Мне кажется такой подход пригоден лишь для обобшения процедуры

A>фиксирования исключений, но ни как для их обработки

Угу, но это уже очень не мало. Я когда сократил число катчей с 4 до 2 (перехват excеption и использование dymanic_cast) двух-мегабайтный COM-модуль похудел на 100K. Теперь я знаю как еще 100K выгадать

Кроме того за счет такой фичи можно ... короче, можно писать по-настоящему интересные приложения на плюсах. От которых программеров на других языках вывернет буквально наизнанку
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[4]: подход к try-catch
От: aton Россия http://ruby.inuse.ru
Дата: 05.10.05 17:28
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, aton, Вы писали:


A>>Мне кажется такой подход пригоден лишь для обобшения процедуры

A>>фиксирования исключений, но ни как для их обработки

КД>Угу, но это уже очень не мало. Я когда сократил число катчей с 4 до 2 (перехват excеption и использование dymanic_cast) двух-мегабайтный COM-модуль похудел на 100K. Теперь я знаю как еще 100K выгадать


КД>Кроме того за счет такой фичи можно ... короче, можно писать по-настоящему интересные приложения на плюсах. От которых программеров на других языках вывернет буквально наизнанку


например ?
Re[4]: подход к try-catch
От: aton Россия http://ruby.inuse.ru
Дата: 05.10.05 17:36
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

DEA>Здравствуйте, aton, Вы писали:


DEA>>>ЗЫ. Естественно, фильтров и их вариаций может быть много...


A>>как правило для каждой функции/метода своя особенная обработка исключении,

A>>а это означает что таких фильтров будет либо очень много, либо их логика будет слишком запутанной.
DEA>...Эта штука может реально пригодиться (я ее так испоьзую) для трансляции "чужих" исключений в исключения базирующиеся на "std::exception" и дальнейшего их rethrow-а. Дело в том, что часто приходится использовать "старые" библиотеки, которые еще не слышали о std::exception и поэтому бросаются всякой фигней вместо нормальных исключений.

А нахрена, что бы протолкнуть исключение вниз, на следующий обработчик? обычно все делается не отходя от кассы

A>>К тому же из ExceptionFilter достаточно проблематично повторно вызвать функцию/метод кидающую исключение.

DEA>Повторно??? А зачем? Чтобы еще раз получить исключение?

Хм... нет, что бы исправить ситуацию и повторить действие, например кончилось место на диске, получили ексепшн,
пользователь подчистил диск, нажал retry, повторили вызов и все заработало

A>>Мне кажется такой подход пригоден лишь для обобшения процедуры фиксирования исключений,

DEA>+1
Re[5]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.10.05 18:12
Оценка:
Здравствуйте, aton, Вы писали:

A>>>Мне кажется такой подход пригоден лишь для обобшения процедуры

A>>>фиксирования исключений, но ни как для их обработки

КД>>Угу, но это уже очень не мало. Я когда сократил число катчей с 4 до 2 (перехват excеption и использование dymanic_cast) двух-мегабайтный COM-модуль похудел на 100K. Теперь я знаю как еще 100K выгадать


Я тут чего-то с арифметкой напутал ... или с логикой Один катч из 2х все равно должен остаться. 50K на катч ...

КД>>Кроме того за счет такой фичи можно ... короче, можно писать по-настоящему интересные приложения на плюсах. От которых программеров на других языках вывернет буквально наизнанку


A>например ?


Я думал про построение обобщенных фреймворков. Например, у меня есть библиотека для построения COM-модулей. Она ориентирована на перехват, обработку и обратную трансляюцию исключений базирующихся на std::exception.
HRESULT OLE_ProcessErrorException(REFCLSID              ComponentID,
                                  REFIID                InterfaceID,
                                  const std::exception* pExc,
                                  bool                  TranslateAllException)
{
 HRESULT hr=E_FAIL;

 try
 {
  if(g_OLE_ErrorExceptionHandler!=NULL)
  {
   //call user handler of exceptions
   hr=g_OLE_ErrorExceptionHandler(ComponentID,InterfaceID,pExc,TranslateAllException);
  }
  else
  if(pExc==NULL)
  {
   //unknown exception
   hr=E_UNEXPECTED;
  }
  else
  if(const t_base_com_error* const x=dynamic_cast<const t_base_com_error*>(pExc))
  {
   //create std object of automation error
   hr=x->create_error_info(InterfaceID);
  }
  else
  if(dynamic_cast<const bad_alloc*>(pExc)!=NULL)
  {
   hr=E_OUTOFMEMORY;
  }
  else
  {
   const char* const what=pExc->what();

   hr=E_FAIL;

   if(what!=NULL && (*what)!=0)
    ole_lib::CreateErrorInfo(InterfaceID,what,hr);
  }//else
 }
 catch(...)
 {
  hr=E_FAIL;
 }

 return hr;
}//OLE_ProcessErrorException


Все работает, но меня постоянно долбит мысль о еще одном базовом классе исключений — Exception из VCL, который (в модулях с GUI) тоже может прорваться до этого обработчика. К сожалению только в виде pExc=NULL.

Вот тут-то стратегия нашего убийцы и поможет ...

Правда мысль о том, что фильтр исключений может быть вызван не из catch(){ }, чего-то меня настораживает. Это раз.

Хотя, по-моему, в плюсах есть средство определения — "Мы сейчас обрабатываем исключение или нет?"

Второе: ведь можно писать так
catch(const exception& e)
{
 throw;
}


Ладно, я тут начал уже погружаться в собсвенные мысли...
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[6]: подход к try-catch
От: Tom Россия http://www.RSDN.ru
Дата: 06.10.05 06:24
Оценка: +1
КД>
КД> catch(...)
КД> {
КД>  hr=E_FAIL;
КД> }
КД>}//OLE_ProcessErrorException
КД>


Вот тут вся красота С++ и исключения жёстко убивается подходом "задавим все исключения и не дадим шанс разработчику узнать а что же таки произошло на самом деле"
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[7]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 06.10.05 06:48
Оценка: +1
Здравствуйте, Tom, Вы писали:

КД>> catch(...)
КД>> {
КД>>  hr=E_FAIL;
КД>> }
КД>>}//OLE_ProcessErrorException


Tom>Вот тут вся красота С++ и исключения жёстко убивается подходом "задавим все исключения и не дадим шанс разработчику узнать а что же таки произошло на самом деле"


А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?

У нас с вами идентичное представление о назначении OLE_ProcessErrorException? Эта центральная функция обработки исключений, сгенерированных внутрях реализаций COM-объектов. И эта обработка тоже может сгенерировать исключение

Или вы предлагаете мне его выпускать наружу? Сомневаюсь, что клиенту COM-объекта это понравится
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[8]: подход к try-catch
От: Tom Россия http://www.RSDN.ru
Дата: 06.10.05 06:56
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, Tom, Вы писали:


КД>
КД>>> catch(...)
КД>>> {
КД>>>  hr=E_FAIL;
КД>>> }
КД>>>}//OLE_ProcessErrorException
КД>


Tom>>Вот тут вся красота С++ и исключения жёстко убивается подходом "задавим все исключения и не дадим шанс разработчику узнать а что же таки произошло на самом деле"


КД>А что вы предлагаете делать для исключений, которые произошли во время обработки исключения?


КД>У нас с вами идентичное представление о назначении OLE_ProcessErrorException? Эта центральная функция обработки исключений, сгенерированных внутрях реализаций COM-объектов. И эта обработка тоже может сгенерировать исключение


КД>Или вы предлагаете мне его выпускать наружу? Сомневаюсь, что клиенту COM-объекта это понравится

Что угодно но ге гасить его таким образом, нормальное правило работы с исключениями — перехватывай то, что выкидываешь
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[9]: подход к try-catch
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 06.10.05 07:22
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Что угодно, но ге гасить его таким образом,

По-подробнее пожалуйста. Писать в файл? Гы. В журнал событий? Возможно, но пусть это делает g_OLE_ErrorExceptionHandler.

>нормальное правило работы с исключениями — перехватывай то, что выкидываешь

И что, это правило распространяется и на обработку исключений, которые произошли во время обработки исключения? Для всех типов приложений?

Еще раз повторю, это функция для обработки исключений. Может вызвать другую функцию, а может выполнить обработку по-умолчанию. И уже звиняте — рекурсивные исключение наружу она не выпустит. Потому что "ружа" — инородная среда, которая про исключения может вообще ничего не знать. Поэтому OLE_ProcessErrorException и давит повторные исключения у себя внутрях на корню.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.