| 
| 
 | Вопрос # 1 961/ вопрос открыт / | 
 |  Здравствуйте, эксперты!У меня почему-то не работают инструкции такого вида:
 try
 выражение с возможной ошибкой;
 except on EAccessViolation do showmessage('MyError');
 end;
 Приложение завершается аварийно. Что-то в опциях компилятора (Delphi 2009) включить или отключить нужно ?
 
|  |   Вопрос задал: Сергей П. (статус: Посетитель)Вопрос отправлен: 3 октября 2008, 15:16
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: Мережников Андрей Здравствуйте, Сергей П.!Если запускаете приложение из под Delphi, то так и будет. Отладчик перехватывает исключения. Чтобы отключить этот перехват (что не сильно рекомендуется, поскольку могут быть и другие ошибки), надо зайти в
 опции Debugger (к сожалению где в Delphi2009 находится эта вкладка не знаю), а в Delphi 6 на вкладку
 Language Exceptions и убрать галочку в checkbox StopOnDelphiExceptions. Либо попробуйте запустить приложение из Windows без Delphi
 
|  | Ответ отправил: Мережников Андрей (статус: Абитуриент)Время отправки: 3 октября 2008, 15:25
 
 |  
 Мини-форум вопросаВсего сообщений: 18; последнее сообщение — 3 октября 2008, 20:51; участников в обсуждении: 4. 
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 15:38 [#1]:Убрал аналогичную галочку у себя. Теперь сообщения об ошибке нет, только звук "критической ошибки" и из под Delphi и из Windows. Программа все равно завершается аварийно. |  
|   | Feniks (статус: Бакалавр), 3 октября 2008, 15:42 [#2]:А зачем вы пытаетесь именно EAccessViolation поймать ? Или, если вам надо поймать любое исключение, то уберите эти строки и оставте только: 
 try
// чего-нибудь
except
   ShowMessage('MyError');
end; |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 16:42 [#3]:А потому что именно EAccessViolation только может появиться, но дело в том что, что не лови - не ловит. |  
|   | Feniks (статус: Бакалавр), 3 октября 2008, 16:48 [#4]:А вот и не только EAccessViolation может быть. Существует целый класс исключительных ошибок. Тогда приводите свой полный код. Посмотрим что там не так.
  ) |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 17:01 [#5]:var CityCodes : Array of integer; ...........
 SetLength(CityCodes,CityCount);
 ...........
 procedure TForm1.ChangeFlashInformer;
 var
 Astr : string;
 dwConnectionTypes: DWORD;
 begin
 if InternetGetConnectedState(@dwConnectionTypes,0) then
 begin
 try
 Astr:=IntToStr(CityCodes[RibbonComboBox2.Items.IndexOf(RibbonComboBox2.Text)]);
 except// on EAccessViolation do showmessage('MyError');
 showmessage('MyError');
 end;
 if Length(Astr)=4 then Astr:=StringOfChar('0',5-Length(Astr))+Astr;
 ShockwaveFlash1.Movie:='http://img.gismeteo.Ru/flash/fw120x60.swf?index='+Astr;
 ShockwaveFlash1.Visible:=True;
 ShockwaveFlash1.Play;
 end
 else
 begin
 ShockwaveFlash1.Stop;
 ShockwaveFlash1.Visible:=False;
 Timer2.Enabled:=True;
 end;
 end;
 
 В случае если RibbonComboBox2.Text = '' то появляется ошибка
 |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 17:09 [#6]:Поправка if Length(Astr)<5 then Astr:=StringOfChar('0',5-Length(Astr))+Astr;
 
 Прошу прощения - проблемы у провайдера, перезашел с телефона, могу пропадать.
 |  
|   | Мережников Андрей (статус: Абитуриент), 3 октября 2008, 17:55 [#7]:Если RibbonComboBox2.Text = '' , то, скорее всего IndexOf() возвращает отрицательное значение из-за этого и ошибка. Надо не try except использовать, а предотвратить возникновение ошибки, поставив проверку, чтобы при text='' обрабатывалась данная ситуация |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 18:13 [#8]:Я так и сделал (пока). Просто для работы программы нужен (и есть) текстовый файл, в котором все по определенному формату прописано. И если пользователь туда руками полезет, то программа начнет ломаться в разных частях (в зависимости от того что пользователь "подправил"). Вот и хотел чтобы не отслеживать, что он там наменял (вариантов много) и не вставлять по всему коду проверки на разные несоответствия, поставить перед фактом ShowMessage('Поменял ? До свидания !'). Т.е. проверять не все возможные ошибки в каждой процедуре, а один раз с помощью try except. А компилятор так не хочет. |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 18:26 [#9]:И еще, TForm1.ChangeFlashInformer вызывается из процедуры, в которой есть такой фрагмент 
 procedure TForm1.SitiesListCreate;
 ......
 if CityCount<=0 then
 begin
 ShowMessage('В списке должен быть хотя бы один город');
 Application.Terminate;
 end;
 .....
 
 Так я сначала хотел сообщать об ошибке, но так как TForm1.SitiesListCreate вызывается из Form1.Create, то программа хочет доделать все что там прописано, и не обращает внимания на Application.Terminate. Вернее обращает но после того как все выполнит, в том числе и код где ошибка появляется.
 |  
|   | Вадим К (статус: Академик), 3 октября 2008, 19:03 [#10]:Application.Terminate в Form1.Create не может просто физически отработать - объект Application просто ещё не настроен. попробуйте в наглую давать halt(1); хотя это и очень грубо. Надо просто переписать нормально код.
 По поводу проверок. А прийдётся их проставлять! без этого никак. правда можно установить общий обработчик на ошибки и генерировать исключения.
 тогда код такой будет
 if (что то не так) then raise exception.create('бай-бай');
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 19:12 [#11]:Так если я все условия возникновения ошибки предусмотрю, хотя это наверно не возможно, то для чего тогда конструкция try except ? Почему она не работает ?
 |  
|   | Вадим К (статус: Академик), 3 октября 2008, 19:42 [#12]:она работает. просто Вы не умеете её пользоваться  А ошибки не надо "предусматривать". надо просто нормально обрабатывать. Не надеятся, что в 2 позиции в 5 строке будет цифра. А взять и проверить.
 Да, парсинг файлов- тяжёлое дело. Но потом привыкаешь и всё просто.
 
 Я обычно делаю так. У меня есть одна процедура, которая загружает файл. Только в одном месте, я не разношу на сотню мест загрузку.
 И эту процедуру в месте вызова заключаю в try except
 И у меня не возникает подобных вопросов.
 Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Вадим К (статус: Академик), 3 октября 2008, 19:44 [#13]:да, подсказка. Если в процедуре нет блока try except, то происходит так называемая раскрутка стека. То есть происходит досрочный выход с процедуры/функции. Если и в вышестоящей нет защитного блока, то ещё выше. Процедуры обработки нажатия кнопок и другие события имеют этот блок неявно. Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 20:23 [#14]:Мне кажется у меня проблема именно в том что вообще эта конструкция не работает. Специально уже деление на 0 туда запихал, а реакции от try except нет. |  
|   | Вадим К (статус: Академик), 3 октября 2008, 20:29 [#15]:ну не может так быть. код в студию Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 20:35 [#16]:В другом фрагменте кода всё работает, а в этом, который здесь обсуждается нет. Чем то в нем не так. |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 20:36 [#17]:А код выше выкладывал, именно в нем не работает. |  
|   | Сергей П. (статус: Посетитель), 3 октября 2008, 20:51 [#18]:Все, всем спасибо, разобрался. Не в том месте Application.Terminate стояло, и не давало моему сообщению появиться. |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |