Exceptions BUG ?
От: exfix  
Дата: 14.07.05 10:03
Оценка:
Есть следующая программа.

using System;

namespace ConsoleApplication1
{
    
    class GenericException : Exception
    {
    }
    class ChildExceptionA : GenericException
    {
    }
    class ChildExceptionB : GenericException
    {
    }
    
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            try
            {
                try
                {
                    Console.WriteLine("Before B thrown");
                    throw new ChildExceptionB();
                }
                catch(ChildExceptionB)
                {
                    Console.WriteLine("Got B exception !");
                    Console.WriteLine("Catch block throws A!");
                    throw new ChildExceptionA();
                }
                finally
                {
                    Console.WriteLine("Finally block throws B!");
                    throw new ChildExceptionB();
                }
            }
            catch(GenericException gex)
            {
                Console.WriteLine("Caught " + gex.GetType().ToString());
                Console.ReadLine();
            }
        }
    }
}


Есть ее вывод :

Before B thrown
Got B exception !
Catch block throws A!
Finally block throws B!
Caught ConsoleApplication1.ChildExceptionB


Внимание вопрос! Куда делся ChildExceptionA ?



29.08.05 06:36: Перенесено из 'Философия программирования'
Re: Exceptions BUG ?
От: Banch  
Дата: 14.07.05 10:14
Оценка:
Не надо в finally кидаться excepetion, это плохо заканчивается.

Проблема в том, что ExceptionA некуда девать, когда возникает excepetion в finally. И оно выбрасывается.
Re: Exceptions BUG ?
От: Oyster Украина https://github.com/devoyster
Дата: 14.07.05 10:22
Оценка:
Здравствуйте, exfix, Вы писали:

E>
// ...
E>                catch(ChildExceptionB)
E>                {
E>                    Console.WriteLine("Got B exception !");
E>                    Console.WriteLine("Catch block throws A!");
E>                    throw new ChildExceptionA();
E>                }
E>                finally
E>                {
E>                    Console.WriteLine("Finally block throws B!");
E>                    throw new ChildExceptionB();
E>                }
E>            }
// ...
E>


E>Внимание вопрос! Куда делся ChildExceptionA ?


Это не баг, это C# by design. Два исключения "сразу" бросить не получится, поэтому выжило только исключение из finally (поскольку оно было брошено позже). Имхо вполне логично.
Re[2]: Exceptions BUG ?
От: exfix  
Дата: 14.07.05 10:30
Оценка:
Здравствуйте, Banch, Вы писали:

B>Не надо в finally кидаться excepetion, это плохо заканчивается.


B>Проблема в том, что ExceptionA некуда девать, когда возникает excepetion в finally. И оно выбрасывается.


Угумс Так оно и есть.
Но допустим что throw происходит не напрямую а допустим так.

finally
{
   MyMegaObject.Close();
}

и внутрях этого самого мегаобжекта юросается иксепшен. Чито тогда ?

Самое интересное, что в Java то же самое. только что проверял.

Представим себе ситуацию. Пусть притянутую за уши. Но тем не менее.
Человек переводит деньги.
Как это обычно делается сначала мы снимаем эти деньги с его счета. Через веб-сервис или еще как. Ок. Деньги снялись.

Потом при попытке записать данные в нашу базу возникает иксепшен (который в кетче). Допустим криворукий программист не обработал какое-то внутреннее исключение.

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

Естественно обрабатывается
finally

Где мы по логике должны закрыть коннекшен с глючной базой. Мы его пытаемся закрыть.. вываливается какой-нить банальный иксепшен типа недостаточно прав на запись или nullReference или еще какая бяка.

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

Трабля однака. Нельзя забивать на иксепшены.
Если иксепшены кто-то кидает значит это кому-нибудь нужно ! (с)
Re[3]: Exceptions BUG ?
От: Oyster Украина https://github.com/devoyster
Дата: 14.07.05 10:51
Оценка: +1
Здравствуйте, exfix, Вы писали:

[... skipped ...]

Представим себе другую ситуацию. Допустим, человек переводит деньги. Снимает их с одного счёта и переводит на другой, но в пределах одной транзакции (а разве бывает иначе в нормальных системах?). Тогда при любой бяке транзакция откатывается назад и у нас всё в ажуре.

Так что проблемы, как правило, не от плохого дизайна, а от тех, кто этот дизайн плохо использует.
Re[4]: Exceptions BUG ?
От: exfix  
Дата: 14.07.05 11:00
Оценка:
Здравствуйте, Oyster, Вы писали:

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


O>[... skipped ...]


O>Представим себе другую ситуацию. Допустим, человек переводит деньги. Снимает их с одного счёта и переводит на другой, но в пределах одной транзакции (а разве бывает иначе в нормальных системах?). Тогда при любой бяке транзакция откатывается назад и у нас всё в ажуре.


O>Так что проблемы, как правило, не от плохого дизайна, а от тех, кто этот дизайн плохо использует.


Ну я же говорил, что ситуация притянута за уши

Просто меня смущает то, что язык вообще позволяет это делать. И что самое инетресное это нигде не описано.
У меня с мозгами все нормально, и бросаться иксепшенами в файналли это не мои методы.
Но знакомый недавно проходил тестирование, и сообщил о таком вот изврате. Я решил проверить.

По уму надо бы сделать так, чтобы внутри финалли иксешены рассматривались как синтаксические ошибки. Но ведь это почему-то не сделали ? Почему ?

Сначала я грешил на дотнет, потом проверил, в джаве то же самое...

Исходя из этих соображений я и поместил свой пост в "философию".

У кого есть идеи зачем позволять бросаться исключениями в финалли ?
И почему тогда на исключения брошенные внутри кетчей "забивают" ?
Может тут есть какая-то логика все-таки ? или баг ?
Re[4]: Exceptions BUG ?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 14.07.05 11:04
Оценка:
Здравствуйте, Oyster, Вы писали:

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


O>[... skipped ...]


O>Представим себе другую ситуацию. Допустим, человек переводит деньги. Снимает их с одного счёта и переводит на другой, но в пределах одной транзакции (а разве бывает иначе в нормальных системах?). Тогда при любой бяке транзакция откатывается назад и у нас всё в ажуре.


А мне доводилось наблюдать ситуации, когда в finally пытались откатывать транзакцию, но перед самым откатом какая-то левая функция генерировала исключение и откат уже не выполнялся. А выход был прост -- не вызывать в finally функций, которые могут генерировать исключения (такие действия лучше оборачивать вспомогательными функциями, не выпускающими исключения наружу). Почти как в C++ с идиомой RAII и дисциплиной небросающих исключения десктрукторов.

O>Так что проблемы, как правило, не от плохого дизайна, а от тех, кто этот дизайн плохо использует.


Так это всегда так.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: Exceptions BUG ?
От: Banch  
Дата: 14.07.05 11:13
Оценка:
E>У кого есть идеи зачем позволять бросаться исключениями в финалли ?
Ну запретить это сложно, ведь exception ожет вылететь где угодно.
Например OutOfMemory

E>И почему тогда на исключения брошенные внутри кетчей "забивают" ?

Никто на них не забивает, надо всегда делать так:
catch( Exception oldException ) {
...
throw new Exception( oldException, .... );
}


Возможно стоило подцеплять к exception из finally ещё и exception из catch, но тогда получался бы древовидный StackTrace
Re[6]: Exceptions BUG ?
От: exfix  
Дата: 14.07.05 11:23
Оценка:
Здравствуйте, Banch, Вы писали:

E>>У кого есть идеи зачем позволять бросаться исключениями в финалли ?

B>Ну запретить это сложно, ведь exception ожет вылететь где угодно.
B>Например OutOfMemory

Ну тогда соответственно вопрос. что же это за try/catch которые не ловят бросаемых иксепшенов ?

B>Никто на них не забивает, надо всегда делать так:

B>catch( Exception oldException ) {
B>...
B>throw new Exception( oldException, .... );
B>}
Ну сделать то можно, только все равно его finally своим иксепшеном затрет..

B>Возможно стоило подцеплять к exception из finally ещё и exception из catch, но тогда получался бы древовидный StackTrace

идея неплоха. Надо мелкософту подать идею.

Но тем не менее вопрос остатеся.. Может вообще try/catch/finally ущербны изначально ? и надо это делать как-то по другому ? чтобы все ловилось. Какой нить ивент листенер.. и чтобы дергался автоматически при возникновении исключения. Хотя так непонятно в каком порядке будет обрабатываться все это дело. Должен сначала финалли отработать а потом иксепшенЛистенер или как иначе..
Короче
Re[5]: Exceptions BUG ?
От: dshe  
Дата: 14.07.05 11:26
Оценка: +1
Здравствуйте, exfix, Вы писали:

E>Ну я же говорил, что ситуация притянута за уши


E>Просто меня смущает то, что язык вообще позволяет это делать. И что самое инетресное это нигде не описано.

E>У меня с мозгами все нормально, и бросаться иксепшенами в файналли это не мои методы.
E>Но знакомый недавно проходил тестирование, и сообщил о таком вот изврате. Я решил проверить.

E>По уму надо бы сделать так, чтобы внутри финалли иксешены рассматривались как синтаксические ошибки. Но ведь это почему-то не сделали ? Почему ?


Если в .NET и в Java исключения в подобной ситуации игнорируются, то в C++ программа корится (вызывается unexpected, которая вызывает terminate, которая вызывает abort). Трудно сказать, достойная ли это альтернатива. Что касается синтаксических проверок, то их по-моему в принципе сделать невозможно. Тем более, что в .NET все исключения unchecked.
--
Дмитро
Re[7]: Exceptions BUG ?
От: Banch  
Дата: 14.07.05 11:42
Оценка:
E>Но тем не менее вопрос остатеся.. Может вообще try/catch/finally ущербны изначально ? и надо это делать как-то по другому ? чтобы все ловилось.

можно писать в стиле низкоуровневого API, чтоб все методы возвращали код выполнения
Re[8]: Exceptions BUG ?
От: exfix  
Дата: 14.07.05 11:52
Оценка:
Здравствуйте, Banch, Вы писали:

E>>Но тем не менее вопрос остатеся.. Может вообще try/catch/finally ущербны изначально ? и надо это делать как-то по другому ? чтобы все ловилось.


B>можно писать в стиле низкоуровневого API, чтоб все методы возвращали код выполнения

но что делать если внутри метода написанного в стиле низкоуровнеаого API произойдет Exception ?
Re[6]: Exceptions BUG ?
От: exfix  
Дата: 14.07.05 12:22
Оценка:
Здравствуйте, dshe, Вы писали:

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


E>>Ну я же говорил, что ситуация притянута за уши


E>>Просто меня смущает то, что язык вообще позволяет это делать. И что самое инетресное это нигде не описано.

E>>У меня с мозгами все нормально, и бросаться иксепшенами в файналли это не мои методы.
E>>Но знакомый недавно проходил тестирование, и сообщил о таком вот изврате. Я решил проверить.

E>>По уму надо бы сделать так, чтобы внутри финалли иксешены рассматривались как синтаксические ошибки. Но ведь это почему-то не сделали ? Почему ?


D>Если в .NET и в Java исключения в подобной ситуации игнорируются, то в C++ программа корится (вызывается unexpected, которая вызывает terminate, которая вызывает abort). Трудно сказать, достойная ли это альтернатива. Что касается синтаксических проверок, то их по-моему в принципе сделать невозможно. Тем более, что в .NET все исключения unchecked.


Ну почему же нельзя.. Допустим тот же throws джавовский.. Если метод бросающий иксепшенами используется в финалли то запретить такое использование.. javac кстати выводит ворнинг по поводу того, "finally block does not complete normally". Но как ворнинг. почему бы не сделать запрет ?
Re[7]: Exceptions BUG ?
От: dshe  
Дата: 14.07.05 12:44
Оценка:
Здравствуйте, exfix, Вы писали:

E>>>По уму надо бы сделать так, чтобы внутри финалли иксешены рассматривались как синтаксические ошибки. Но ведь это почему-то не сделали ? Почему ?


D>>Если в .NET и в Java исключения в подобной ситуации игнорируются, то в C++ программа корится (вызывается unexpected, которая вызывает terminate, которая вызывает abort). Трудно сказать, достойная ли это альтернатива. Что касается синтаксических проверок, то их по-моему в принципе сделать невозможно. Тем более, что в .NET все исключения unchecked.


E>Ну почему же нельзя.. Допустим тот же throws джавовский.. Если метод бросающий иксепшенами используется в финалли то запретить такое использование.. javac кстати выводит ворнинг по поводу того, "finally block does not complete normally". Но как ворнинг. почему бы не сделать запрет ?


checked исключения отследить можно (что javac и делает), невозможно отследить unchecked исключения.
--
Дмитро
Re: возможное решение ?
От: exfix  
Дата: 14.07.05 13:00
Оценка:
плюнуть на finally и делать так.

exception=0;
try {
} catch () {
exception=1;
}

if (exception) {
}


Но вопрос остается ? Зачем делали Finally ? проектировали язык то неглупые люди.
Re[9]: Exceptions BUG ?
От: Banch  
Дата: 14.07.05 13:10
Оценка:
E>но что делать если внутри метода написанного в стиле низкоуровнеаого API произойдет Exception ?

а он не должен использовать методы, которые могут кинуть exception
только те, что возвращают код ошибки
Re[2]: возможное решение ?
От: qwier Украина  
Дата: 14.07.05 19:04
Оценка:
Здравствуйте, exfix, Вы писали:

E>плюнуть на finally и делать так.


E>
E>exception=0;
E>try {
E>} catch () {
E>exception=1;
E>}

E>if (exception) {
E>}
E>


E>Но вопрос остается ? Зачем делали Finally ? проектировали язык то неглупые люди.


Например потому что в такой ситуации

try 
{ 
  ... 
} 
catch () 
{
    throw его дальше куда-то
}
finally 
{
  ...    
}


finally все равно выполнится.
... << RSDN@Home 1.1.4 beta 7 rev. 472>>
Re[5]: Exceptions BUG ?
От: IT Россия linq2db.com
Дата: 15.07.05 04:53
Оценка:
Здравствуйте, eao197, Вы писали:

E>А мне доводилось наблюдать ситуации, когда в finally пытались откатывать транзакцию, но перед самым откатом какая-то левая функция генерировала исключение и откат уже не выполнялся.


Rollback вообще вызывать не обязательно, транзакция откатится при закрытии коннекции. Вызывать обязательно только Commit
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Exceptions BUG ?
От: Павел Кузнецов  
Дата: 19.07.05 05:48
Оценка: +2
dshe,

d> Если в .NET и в Java исключения в подобной ситуации игнорируются, то в

d> C++ программа корится (вызывается unexpected, которая вызывает
d> terminate, которая вызывает abort). Трудно сказать, достойная ли это
d> альтернатива.

Это просто две разные философии.

В C++ считается, что если программа не смогла восстановиться в результате исключения, то продолжать
исполнение нельзя, т.к. в общем случае она находится в непредсказуемом состоянии.

В C#/Java считается, что если программа не смогла восстановиться в результате исключения, то нужно
надеяться на лучшее: вдруг, повезет, и программа окажется в приемлемом для дальнейшего исполнения
состоянии...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.