Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Когда подавлять исключения а когда пропускать? / 25 сообщений из 69, страница 1 из 3
11.02.2014, 16:02
    #38557332
FatherSql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
пусть есть функция func в которой может возникнуть исключение. У нас есть 2 варианта
1. поймать в ней исключение и вернуть какойто результат типа
bool func()
{
bool res = true;

try
{
}
catch()
{
res = false;
}

return res;
}

2. Можно не ловить.

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

void func3()
{
func2();
}

void func2()
{
func();
}

то мы задолбаемся прокидывать наверх какие то осмысленные коды возврата (если это не тру фалс конечно, так действительно просто).

Вот интересует как лучше?
...
Рейтинг: 0 / 0
11.02.2014, 16:17
    #38557351
WebSharper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Подавлять никогда не надо - либо обрабатываешь осмысленно, либо отправляешь выше, возможно оборачивая в исключение более высокого уровня (типа "не смог импортировать файл (потому, что доступ запрещен)")
...
Рейтинг: 0 / 0
11.02.2014, 16:49
    #38557388
iv_an_ru
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
FatherSql,

Пусть есть маленькая комната с кафельным полом. У нас есть два варианта:
1. Поставить ванну.
2. поставить унитаз.
Вот интересует как лучше.
...
Рейтинг: 0 / 0
11.02.2014, 20:17
    #38557685
skyANA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
WebSharperПодавлять никогда не надо - либо обрабатываешь осмысленно, либо отправляешь выше, возможно оборачивая в исключение более высокого уровня (типа "не смог импортировать файл (потому, что доступ запрещен)")+1
...
Рейтинг: 0 / 0
12.02.2014, 01:46
    #38557946
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
FatherSql, обычно придерживаются такой стратегии что исключения
не должны "частить". Или дёргаться часто. На сотни-тысячи успешных
callbacks у вас должен быть один исключительный. Исключения (в зависимости
от реализации могут быть "дорогими в обслуживании". Они могут где-то выделять
память. Поэтому не стоит их толкать внутрь цикла где факт исключения "зымыливается"
и цикл повторяется Это bad practice. По возможности лучше использовать
коды возврата если по смыслу callback это позволяет.

Исключения удобно применять тогда где нужно "аварийно завершить всё".
Например - отъехал сетевой диск. Вы сворачиваете весь стек вызовов
который работает с ним.

Остальное - вопросы дизайна вашей библиотек и предмет договрённостей
между вами и теми кто эту библиотеку будет использовать. Обычно вы не
кодите в вакууме. Вы оглядываетесь по сторонам. Смотрите как пишут
в team, в проекте в корпорации или какие code conventions.
...
Рейтинг: 0 / 0
12.02.2014, 14:17
    #38558472
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Ребята, все конкретики языка программирования и задачи эти все обсуждения бессмысленны.
Нет общих правил, когда как нужно обрабатывать исключения.
...
Рейтинг: 0 / 0
12.02.2014, 18:43
    #38558930
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
FatherSqlпусть есть функция func в которой может возникнуть исключение. У нас есть 2 варианта
1. поймать в ней исключение и вернуть какойто результат типа
Это редко является хорошим подходом. Собственно, я пожалуй что рискну утверждать, что во всех случаях, когда вообще стоит выбор "первый или второй вариант", первый явно не стоит использовать.

FatherSqlТак вот я про плюсы второго метода, собсвтенно он один - меньше кода,
Его главный плюс в том, что он гораздо надёжнее, по крайней мере "в среднем по больнице".
...
Рейтинг: 0 / 0
12.02.2014, 20:55
    #38559045
FatherSql
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
softwarerFatherSqlпусть есть функция func в которой может возникнуть исключение. У нас есть 2 варианта
1. поймать в ней исключение и вернуть какойто результат типа
Это редко является хорошим подходом. Собственно, я пожалуй что рискну утверждать, что во всех случаях, когда вообще стоит выбор "первый или второй вариант", первый явно не стоит использовать.

FatherSqlТак вот я про плюсы второго метода, собсвтенно он один - меньше кода,
Его главный плюс в том, что он гораздо надёжнее, по крайней мере "в среднем по больнице".
чем надежнее
...
Рейтинг: 0 / 0
12.02.2014, 21:07
    #38559055
Вася Уткин
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Про обработку исключений говорят правильно, это идет из старых умных книжек, но сейчас в C++ часто вся обработка заключается в выходе из области видимости с вызовом деструкторов, а в catch() просто сообщается факт ошибки пользователю.

Я использую исключения в случаях:
1. Когда удобно получать полезное возвращаемое значение:
Код: plaintext
1.
2.
3.
4.
try {
 str = get_par_str();
 // ...
}


2. Когда при ошибке не имеет смысла использовать полученные данные из функции и вся обработка исключения заключается в выходе из области видимости и вызове деструкторов:
Код: plaintext
1.
2.
3.
4.
5.
try { 
 auto ptr = get_instance();
 // ...
} 
catch (...) { /* empty or std::cout */ } 


2. Когда одни и те же исключения могут выйти из нескольких функций:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
try {
 func1();
 func2();
 func3();
 func4();
} 
catch(std::bad_alloc &ba) { /* something */ }
catch(...) { /* something */ } 



В остальных случаях return. В частности когда функцию пишет другой человек, в ней может возникнуть несколько разных исключений, причем их количество и тип может меняться разработчиком функции, то лучше, чтобы в самом интерфейсе функции была заложена классификация и сквозная нумерация ошибок, т.е. в h-файле enum который и возвращается. Но и в этом правиле бывают исключения.
...
Рейтинг: 0 / 0
12.02.2014, 21:57
    #38559091
Вася Уткин
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Допустим если функция имеет такой вид:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
func() {

 try { 
  auto str = get_par_str();
  // ...

  auto ptr = get_instance();
  // ...

  auto obj = get_some_obj();
  // ...


 } // automatic calls destructors for solve exceptions
 catch (std::bad_alloc &ba) { std::cout << ba.what() << std::endl; /* something */ } 
 catch (std::runtime_error &rt) { std::cout << rt.what() << std::endl; /* something */ } 
 catch (std::exception &ex) { std::cout << ex.what() << std::endl; /* something  */ } 
 catch (...) { std::cout << "Unknown exception"<< std::endl; /* something  */ } 

 // ...
}



С return и кодам ошибок выглядело бы так - больше кода и больше вложенности:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
func() {


 {
  errcode1_t errcode1;
  std::string str
  if (!(errcode1 = get_par_str(&str))) {
   switch(errcode1) {
    case err1_1: /* */ break;
    case err1_2: /* */ break;
    case err1_3: /* */ break;
    default: std::cout << "Unknown error"<< std::endl; break;
   }
  } else {
   // ...

   errcode2_t errcode2;
   std::shared_ptr<T> ptr;
   if (!(errcode2 = get_instance(&ptr))) {
    switch(errcode2) {
     case err2_1: /* */ break;
     case err2_2: /* */ break;
     case err2_3: /* */ break;
     default: std::cout << "Unknown error"<< std::endl; break;
    }
   } else {
    // ...

    errcode3_t errcode3;
    T2 obj;
    if (errcode3 = get_some_obj(&obj)) {
     switch(errcode3) {
      case err3_1: /* */ break;
      case err3_2: /* */ break;
      case err3_3: /* */ break;
      default: std::cout << "Unknown error"<< std::endl; break;
     }
    } else {
     // ...
   }
  }
 } // automatic calls destructors for solve errors


 // ...
}



И без RAII ещё бы в разы больше кода было.
...
Рейтинг: 0 / 0
12.02.2014, 23:13
    #38559147
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
FatherSqlчем надежнее
Да много чем. Меньше кода - меньше ошибок. Код прозрачнее - меньше ошибок. Легче сопровождение, меньше сил на работу с кодами завершения - итогом всего является "меньше ошибок". Но самое главное - поведение при внесении изменений в другие части программы.

Допустим, у нас в приложении используется некая функция. Всё работает без ошибок. В ходе доработок в ней появился новый код возврата - упс, нужно перепроверять все места её вызова. Если где-то вызывающий код останется "старым", последствия непредсказуемы; в том числе выполнение может пойти по ветке кода OK.

Теперь та же ситуация, но в функцию добавлено новое исключение. Что происходит со старым кодом? Да ничего страшного, собственно. Исключение провалится до стандартного обработчика, который запишет в лог "произошла неожиданная ошибка такая-то", либо вообще не будет обработано и повалит приложение. То есть по крайней мере приложение не будет делать вид, что всё в порядке, не испортит данные и не попытается обработать ошибку А методами ошибки Б.
...
Рейтинг: 0 / 0
13.02.2014, 08:29
    #38559303
eNose
Участник
[не активирован]
[не одобрен]
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
softwarerВ ходе доработок в ней появился новый код возврата - упс, нужно перепроверять все места её вызова. Изначально надо писать код так, что необрабатываемые коды пишут в лог и валят приложение.
Это можно сделать как исключениями, так и проверками кода возврата.
...
Рейтинг: 0 / 0
13.02.2014, 09:00
    #38559330
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
eNoseИзначально надо писать код так, что необрабатываемые коды пишут в лог и валят приложение.
Во-первых, "нужно" не значит "везде будет". Я давно привык закладывать в подходы предположение, что программист ошибётся везде, где у него есть такая возможность. И в этом случае с кодами возврата будет наломано больше дров. Ну а во-вторых, далеко не всегда необрабатываемые коды должны валить приложение. Не так редко отказ какого-то модуля представляется меньшим злом, нежели отказ приложения в целом.
...
Рейтинг: 0 / 0
13.02.2014, 09:49
    #38559382
super-code
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Все твердят, что при неизвестном исключении надо его не обработать (валить приложение) с записью в лог. Хорошая практика.
Да тут все понятно. Но скажите, товарищи, допустим наше приложение - веб-сервер. К которому приходят тысячи запросов. Один из этих запросов привел к неизвестному исключению. Приложение записало это в лог, и упало. 9999 успешно работающих сейчас коннектов завершились. Это Вы называете хорошей практикой?

Иногда можно перехватывать любые исключений, проверять, если это исключение, после которого невозможно работать далее, то валить приложение. Если можно работать дальше, то валить, только эту ветку, а остальная часть кода должна продолжать функционировать. В лог запись конечно таких ошибок должна быть.
...
Рейтинг: 0 / 0
13.02.2014, 10:35
    #38559449
skyANA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
super-codeВсе твердят, что при неизвестном исключении надо его не обработать (валить приложение) с записью в лог. Хорошая практика.
Да тут все понятно. Но скажите, товарищи, допустим наше приложение - веб-сервер. К которому приходят тысячи запросов. Один из этих запросов привел к неизвестному исключению. Приложение записало это в лог, и упало. 9999 успешно работающих сейчас коннектов завершились. Это Вы называете хорошей практикой?Это Вы фигню какую-то выдумали. Отдельный запрос получит 500-ю, или 404-ю (обычно если исключения перехватывают, пишут в лог, то отдают ответ с этим кодом), остальные успешно продолжат работать дальше.
...
Рейтинг: 0 / 0
13.02.2014, 10:44
    #38559469
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
super-codeВсе твердят, что при неизвестном исключении надо его не обработать (валить приложение) с записью в лог. Хорошая практика.
Да тут все понятно. Но скажите, товарищи, допустим наше приложение - веб-сервер. К которому приходят тысячи запросов. Один из этих запросов привел к неизвестному исключению. Приложение записало это в лог, и упало. 9999 успешно работающих сейчас коннектов завершились. Это Вы называете хорошей практикой?
Где уверенность что перед исключением не было записи "мусора" в память, которой пользуется один из 9999 успешных? Можно утверждать что все 9999 вернут достоверный результат?
...
Рейтинг: 0 / 0
13.02.2014, 10:47
    #38559475
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Dima TГде уверенность что перед исключением не было записи "мусора" в память,
Ровно там же, где уверенность, что записи "мусора" в память не было без всякого исключения (или при коде возврата OK). Вы так смешно говорите, словно вызываемый любезно возвращает специальную ошибку, "господа, я насрал вам в оперативку" :)
...
Рейтинг: 0 / 0
13.02.2014, 10:48
    #38559479
super-code
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Dima T, разработчики .NET и IIS windows с Вами не согласны. Проверьте - создайте свой сайт ASP.NET при запросе бросьте своё исключение и не обрабатывайте его. После этого IIS не упадет, а будет нормально работать дальше.
...
Рейтинг: 0 / 0
13.02.2014, 10:49
    #38559482
super-code
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
skyANA, и как же он получит ответ на http-запрос, если в коде не обработаете это исключение? Я Вам про это и вещаю, что иногда надо обрабатывать любое исключение, даже неизвестное.
...
Рейтинг: 0 / 0
13.02.2014, 13:38
    #38559767
Вася Уткин
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
eNosesoftwarerВ ходе доработок в ней появился новый код возврата - упс, нужно перепроверять все места её вызова . Изначально надо писать код так, что необрабатываемые коды пишут в лог и валят приложение.
Это можно сделать как исключениями, так и проверками кода возврата.
Это да! Как и в исключениях они ловятся через catch(...), так и в кодах возврата они ловятся через else в if или в default в case. Но удобство исключений в том, что отлавливать такие неизвестные исключения можно в одном месте сразу для 10 функций, а неизвестные коды возврата надо проверять для каждой функции - больше кода .
...
Рейтинг: 0 / 0
13.02.2014, 13:39
    #38559769
Вася Уткин
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
super-codeИногда можно перехватывать любые исключений, проверять, если это исключение, после которого невозможно работать далее, то валить приложение. Если можно работать дальше, то валить, только эту ветку, а остальная часть кода должна продолжать функционировать. В лог запись конечно таких ошибок должна быть.
Есть и третий вариант, когда неизвестно невозможно или можно работать дальше - неизвестное исключение/код возврата. В этом случае предполагается худший вариант - невозможно.
Но идут всегда на компромисс, просто все потоки и подключения изначально поделены между несколькими процессами с изолированной памятью, и падает только один из процессов. Лучше если 10% соединений передподключатся, чем вместо 1 000 спишется 1 000 000 руб в биллинге.
...
Рейтинг: 0 / 0
13.02.2014, 14:35
    #38559878
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Иногда бывают ситуации когда обрабатывать что-либо уже поздно.
К примеру совершенно непонятно как надо обрабатывать java.lang.OutOfMemoryError.
Оно вроде бы и ежу ясно что постфактумом анализировать увеличивать mX, анализировать
дамп и делать прочие неспешные акты. Но что делать в рилтайме? Вроде уже и нечего.
Можно только рухнуть в лог с уровнем FATAL, или MEGA_FATAL, ... или саркастически
написать какой-то афоризм... типа "Вечны смерть, налоги и нехватка хипа...."
...
Рейтинг: 0 / 0
13.02.2014, 15:07
    #38559925
Вася Уткин
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
maytonкак надо обрабатывать java.lang.OutOfMemoryError. Но что делать в рилтайме?
Закрыть только это соединение с сообщением об ошибке. Остальные соединения уже себе память выделили - пусть работают.
Плюс в такой ситуации можно в течении X минут сразу отлупливать новые соединения, где X - среднее время жизни одного соединения.
...
Рейтинг: 0 / 0
13.02.2014, 15:08
    #38559926
super-code
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Вася Уткинsuper-codeИногда можно перехватывать любые исключений, проверять, если это исключение, после которого невозможно работать далее, то валить приложение. Если можно работать дальше, то валить, только эту ветку, а остальная часть кода должна продолжать функционировать. В лог запись конечно таких ошибок должна быть.
Есть и третий вариант, когда неизвестно невозможно или можно работать дальше - неизвестное исключение/код возврата. В этом случае предполагается худший вариант - невозможно.
Но идут всегда на компромисс, просто все потоки и подключения изначально поделены между несколькими процессами с изолированной памятью, и падает только один из процессов. Лучше если 10% соединений передподключатся, чем вместо 1 000 спишется 1 000 000 руб в биллинге.

И с вами не согласны разработчики .NET и IIS, пример приводил. Также не согласны разработчики ms sql server. Попробуйте в ms sql server зарегистрировать свою сборку, при её вызове бросать exception. Сделайте запрос sql к серверу и с вызовом вашей сборки. Служба sql server не упадет, а только ответит ошибкой - служба обрабатывает любое исключение, даже не зная о чем оно. А если служба знает, что за исключение и уверена, что дальше работать нельзя, то тогда падает. И ни на какие части подключенные к sql server не делятся путем запуска нескольких процессов.
...
Рейтинг: 0 / 0
13.02.2014, 15:12
    #38559933
super-code
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Когда подавлять исключения а когда пропускать?
Вася Уткин, я привел уже пару примеров мировых продуктов, которые обрабатывают любое исключение. И готов привести ещё 10 (если не мировых, то очень известных). А вы можете к своей теории добавить практику - привести пример известного продукта, в который можно внедрять свои разработки, и при неизвестном исключении весь процесс будет падать?
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Когда подавлять исключения а когда пропускать? / 25 сообщений из 69, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]