Войти
ПрограммированиеФорумОбщее

Исключения в C++ (6 стр)

Страницы: 13 4 5 6 7 8 Следующая »
#75
4:09, 17 мая 2018

Коннект тоже иногда случается (в сравнении с получентем данных)

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


#76
4:30, 17 мая 2018

skalogryz
> Дисконнект может быть инициализирован сервером (нр кик от админа), это
> исключение, или часть логики?
> Потому что дисконнект инициализированный клиентом не должен исключения вызвать.
> Так?
Я не пойму о чем мы вообще говорим.
Вот ты вызвал функцию send. Она тебе вернула SOCKET_ERROR, ты вызвал WSAGetLastError и увидел, что это WSAECONNABORTED. Твои действия?

#77
5:22, 17 мая 2018

MrShoor
> Твои действия?
вызову евент, навроде: DoDisconnect(Self, ReasonNetworkError);

но именно обычный евент, а не exception.
я буду боятся делать exception, просто по причине боязни дублирования кода.
Я не хочу, чтобы штатный Disconnect и внештатный ESockError, в итоге всё-равно приводили к исполнению одно и того же кода.
Мне кажется это избыточным, и по-этому OnDisconnect имеет в качестве параметра причину разъединения.

не факт, что такой подход противоречит программному интерфесу. например bool Send(). Метод возвращает true/false, потенциально вызывает евенты OnSent, OnError (ну и как следствие) OnDisconnect

MrShoor
> Я не пойму о чем мы вообще говорим.
о тех случаях когда recv() вернул 0. это исключение?
и в чём будет существенное отличее о того, когда он вернул -1 с тем же WSAECONNABORTED

#78
5:37, 17 мая 2018

skalogryz
> вызову евент, навроде: DoDisconnect(Self, ReasonNetworkError);
> но именно обычный евент, а не exception.
Плохой подход, ибо в месте, где ты получил ошибку у тебя на руках может быть куча ресурсов. Например очередь с пакетами для отправки, которые теперь не имеют смысла, и которые надо слить. Короче это очень стремный код с евентом.
А с исключениями как раз нормальный, потому что ты аккуратно раскручиваешь стек, и выходишь, отпуская все ресурсы, захваченные на стек. Выходишь аккурат до обработчика исключения.

> Я не хочу, чтобы штатный Disconnect и внештатный ESockError, в итоге всё-равно приводили к исполнению одно и того же кода.
Всмысле? Просто вызови функцию из обработчика исключения, какие проблемы то?

try
  if reconnect_required then
  begin
    Disconnect;
    Connect;
  end;
  DoNeworkLogic();
except
  on e: ESockError
  begin
    if e.Code = WSAECONNABORTED then
      reconnect_required := True;
  end;
end;
Все. Тут вызывается тот же самый Disconnect когда пользователь жмет на кнопку разорвать соединение, и тот же самый Connect который происходит, когда пользователь жмет кнопку присоединиться.

#79
5:50, 17 мая 2018

MrShoor
> Плохой подход, ибо в месте, где ты получил ошибку у тебя на руках может быть
> куча ресурсов. Например очередь с пакетами для отправки, которые теперь не
> имеют смысла, и которые надо слить. Короче это очень стремный код с евентом.
функция Send вернёт false.
skalogryz
> например bool Send()
вот, то место, которое занимается посылкой пакетов увидит false, и дальше уже будет их сливать.

Send() возвращает значение послали/непослали. При этом "непослали" априори говорит, что "больше и не пытайтесь посылать"
евент OnDisconnect или OnError - оповещает о причинах (если кому интересно, ведь отсутствие event-а, на общий ход кода не влияет).
(для любителей, можно ошибку уже вместе с объектом сохранить, но это если "объект" есть... хотя с евентами он точно есть)

Оке, вот если такая логика:

try
  if reconnect_required then
  begin
    Disconnect;
    Connect;
  end;
  DoNeworkLogic();
  ..
  // при возникновении ошибки в DoOtherNetworkLogic reconnect_required не нужен
  DoOtherNeworkLogic(); 
except
  on e: ESockError
  begin
    if e.Code = WSAECONNABORTED then
      reconnect_required := True; 
  end;
end;
как решать? добовлять переменные состояния? (прошли DoNetworkLogic или нет)

#80
5:58, 17 мая 2018

skalogryz
> как решать? добовлять переменные состояния?
А что тут решать? Какие ошибки возможны внутри DoOtherNeworkLogic(); ? Если возможна ESockError с кодом WSAECONNABORTED, то что ты будешь делать когда снова дойдем до DoNeworkLogic() ? Ведь пользоваться сокетом уже нельзя.

#81
6:11, 17 мая 2018

MrShoor
> А что тут решать? Какие ошибки возможны внутри DoOtherNeworkLogic(); ? Если
> возможна ESockError с кодом WSAECONNABORTED, то что ты будешь делать когда
> снова дойдем до DoNeworkLogic() ? Ведь пользоваться сокетом уже нельзя.
а, я просто неправильно истолковал назначени флага reconnect_required.

Спрошу подругому:
какой удобный способ узнать в обработчике, в каком из методов DoNetworkLogic() или DoOtherNeworkLogic() произошёл exception (ESockError).
Или, при использовании exception-ов это будет неправильное их использование (неправильное применение концепции исключений)?

#82
6:17, 17 мая 2018

skalogryz
> какой удобный способ узнать в обработчике, в каком из методов DoNetworkLogic()
> или DoOtherNeworkLogic() произошёл exception (ESockError).
А зачем это узнавать, если это одна и та же ошибка?
Не, ну если действительно надо разделить логику (например DoNeworkLogic работает с одним сокетом, а DoOtherNeworkLogic с другим), то просто пишешь так:

try
  if reconnect_required then
  begin
    Disconnect;
    Connect;
  end;
  DoNeworkLogic();
except
  on e: ESockError
  begin
    if e.Code = WSAECONNABORTED then
      reconnect_required := True; 
  end;
end;

try
  DoOtherNeworkLogic(); 
except
  on e: ESockError
  begin
    //another logic
  end;
end;
#83
6:22, 17 мая 2018

MrShoor
> А зачем это узнавать, если это одна и та же ошибка?
хз... для лога например. "такая-то ошибка произшла там-то и там-то"
или в том же диалоговом окне написать, что "при Other Network Logic произошёл перекус кабеля"

честно говоря, я надеялся на другой ответ (- что это неправильная концепция).
Даже если исключение это не всеконецприехали, строить на их основе логику не хочется.
Потому что получается что StrToInt() лучше, чем TryStrToInt() (или StrToIntDef).

#84
6:33, 17 мая 2018

skalogryz
> хз... для лога например. "такая-то ошибка произшла там-то и там-то"
У тебя с исключением полный стектрейс, бери да логгируй.

> или в том же диалоговом окне написать, что "при Other Network Logic произошёл
> перекус кабеля"
Ты в объект исключения можешь напихать что угодно. Хоть пользовательский скриншот.

> Потому что получается что StrToInt() лучше, чем TryStrToInt() (или
> StrToIntDef).
Конкретно StrToInt - это перегиб я считаю. Ну то есть как раз хороший пример, когда от исключения больше вреда, чем пользы. Если программист захочет сделать из этого исключительную ситуацию при неправильной конвертации - то он на TryStrToInt может сам поднять собственное исключение. И это будет правильно идеологически, потому что библиотека пользователя вернет куда более понятное например EParseError, и это исключение уже есть смысл обрабатывать. А вот обрабатывать EConvertError бред полнейший, потому что скорее всего обрабатывать ты его будешь сразу же на месте вызова StrToInt. Короче, я никогда не использую StrToInt, а использую TryStrToInt и StrToIntDef, потому что StrToInt писали какие-то наркоманы хипстеры, которые не понимают идеологию исключений.

#85
6:35, 17 мая 2018

MrShoor
> После AV на write тоже будешь показывать пользователю окошко, и дашь ему
> возможность продолжить?
Долго думал, что это за "AV".
У меня компилятор не ловит сигналы от ОС. :( Приходится проявлять особенную аккуратность на буферах и указателях, и при возможности получить ноль от клиента - проверить на него явно.

Ghost2
> Даже в одном месте memcpy в try завернут.
Лол, серьёзно?
...
О, и правда!
По задумке - это был такой try...finally на IDirect3DVertexBuffer9::Lock, но смотрится и правда глупо. (с учётом, что access violation всё равно не ловятся)
Наверно, надо будет всё-таки запилить более-менее нормальный finally на лямбдах и деструкторах.

skalogryz
> вызову евент, навроде: DoDisconnect(Self, ReasonNetworkError);
А вот жирные коллбеки - вот это уже реально опасно. Входишь, такой, в цикл, начинаешь репликацию, и после очередного send() внезапно обнаруживаешь, что после отправки пакета каким-то образом половина программы поменяла состояние. А вдруг у тебя где-то посреди стека берётся лок?
Плохая идея, в общем. Операции на нижних уровнях абстракции не должны дёргать функции выше себя, иначе опять получается бардак и содомия.

#86
6:37, 17 мая 2018

Delfigamer
> У меня компилятор не ловит сигналы от ОС.
Причем тут компилятор? AV поднимает сама операционная система, и дальше идет раскрутка стека уже не зависящая от тебя. Если у тебя AV от ОС никак не влияет на программу, то значит что у тебя просто там есть заглушка из SEH фрейма.

#87
6:51, 17 мая 2018

MrShoor
> Причем тут компилятор? AV поднимает сама операционная система, и дальше идет
> раскрутка стека уже не зависящая от тебя. Если у тебя AV от ОС никак не влияет
> на программу, то значит что у тебя просто там есть заглушка из SEH фрейма.
Наоборот, AV роняет программу полностью и сразу, игнорируя все возможные try, так что вопрос "что делать" не стоит - делать нечего, программа уже мертва.
Можно, наверно, понаставить обработчиков вручную, но на данный момент смысла в этом нет. Ну поймал я его, а дальше что? Не окошки пользователю рисовать же, в самом деле.

#88
6:54, 17 мая 2018

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

#89
7:15, 17 мая 2018

MrShoor
> Ты в объект исключения можешь напихать что угодно. Хоть пользовательский скриншот.
это всё классно, но только для исключений, которые создаю я.
Но не факт, что ESockError бросает код, который я имею техническую возможность поменять.
Я что-то не припомню возможности вешать произвольные данные на произвольный exception.

+ но можно писать, вот как-то так:

MrShoor
> А вот обрабатывать EConvertError бред полнейший, потому что скорее всего
> обрабатывать ты его будешь сразу же на месте вызова StrToInt.
а это не схоже с твоим предложением обернуть try..except вокруг DoNetworkLogic() и DoOtherNetworkLogic()?
как мне кажется, ты ратуешь за исключения высокоуровненые (которые несут некий логический смысл).
EConvertError - низкоуровневое исключение; (т.к. это ошибка на уровне действия с примитивными типами)
но разъединение сокета, это разве не низкий уровень (с точки зрения сокета же)

MrShoor
> У тебя с исключением полный стектрейс, бери да логгируй
это замечательно, но хочется человекочитаемый, и чтобы сразу там был (у "конечного пользователя").
слишком частный случай, не стоит на нём внимание заострять.

Delfigamer
> А вот жирные коллбеки - вот это уже реально опасно.
ну я же написал, что это функция должна быть! и ещё предложил errorcode собрать... (не возвращать, но оставить с объектом)

Страницы: 13 4 5 6 7 8 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.