На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Как узнать код ошибки try except
    Подскажите, можно ли как нибудь отловить код ошибки?
    Объясняю на примере:
    Вот отлавливает деление на ноль, к примеру:
    ExpandedWrap disabled
      //readln(A);  =0;
      try
      Z:=Z/A;
      except on E: exception do
      ShowMessage(e.messages);
      end;

    Ну это конечно ясно, что он напишет 'Division by zero', но это во-первых по английски, а во вторых, если мы напишем сразу сообщение по русски, т.е. так:
    ExpandedWrap disabled
      //readln(A);  =0;
      try
      Z:=Z/A;
      except
      ShowMessage('Деление на ноль!');
      end;

    и допустим, что ошибка произошла не из-за того, что делится на ноль, а из-за чего-нибудь другова - то естественно сообщение будет ложным, а точнее неверным.
    И что делать? Типа есть такой вариант, но тупой:
    ExpandedWrap disabled
      //readln(A);  =0;
      try
      Z:=Z/A;
      except on E: exception do
      if (e.messages='Division by zero') then ShowMessage('Деление на ноль') else
      ShowMessage(e.messages);
      end;

    Почему вариант тупой, да потому что, перед тем как вставить текст сообщения об ошибке надо:
    1. Сделать эту ошибку
    2. вывести её на экран
    3. скопировать её текст "символ в символ"
    4. потом вставить это сообщение в код для сравнения.

    Хочется что-то типа того, что текст ошибки сообщения мог бы заменять какой-нибудь её индетификатор, чтобы можно было типа такого:
    ExpandedWrap disabled
      //readln(A);  =0;
      try
      Z:=Z/A;
      except on E: exception do
      if (e.код_ошибки=123) then ShowMessage('Деление на ноль') else
      ShowMessage(e.messages);
      end;

    где "123" есть индетификатор ошибки, т.е. заменяет сам текст 'Division by zero'. Да, и у e нет параметра на английском, что я написал на русском код_ошибки.

    Ууууу.... Пока писал - сам устал. :)
    Если кто поймёт меня, помогите разобраться.
        Спасибо за ссылку.
        А вот в каком модуле находятся классы исключений при работе с ibx компонентами.
        Т.е. мне надо вот к примеру такой класс исключения:
        ExpandedWrap disabled
          except
                    on E: EIBInterBaseError do begin
                          sShowMessage(e.ClassName,e.Message);
                          exit;
                          end;

        а он мне пишет: Неизвестная переменная EIBInterBaseError

        Вообще класс такой есть, он даже его показывает, если я делаю так:
        ExpandedWrap disabled
                  try
                  Connected:=true;
                  except
                    on E: exception do
                          sShowMessage(e.ClassName,e.Message);
                    end;

        Вот e.ClassName как раз и есть EIBInterBaseError, только я не могу класс коде указать.
        Сообщение отредактировано: Continental -
          Хелп говорит, что EIBInterBaseError находится в юните IB
            Цитата Continental @
            А вот в каком модуле находятся классы исключений при работе с ibx компонентами.

            Пуск/Поиск. *.pas с текстом EIBInterBaseError.
            Для ускорения поиска лучше ткнуть в папку Delphi.

            Цитата Continental @
            Вообще класс такой есть, он даже его показывает, если я делаю так

            Вместо
            ExpandedWrap disabled
              except
                on E: SomeClass do
                ...


            можно (но не рекомендуется) использовать:
            ExpandedWrap disabled
              except
                on E: Exception do
                  if E.ClassName = 'SomeClass' then
                    ...
                  else
                    raise;
              ММММ.... всё равно прочитав всё, не могу реализовать то что я хочу.
              Вот к примеру:
              1. я указываю несуществующий путь к БД в TIBDataBase. Делаю подключение и try показывает ошибку класса EIBDataBaseError, при этом вот такой текст ошибки: 'I\O Error ....и т.д.'.
              2. я указываю существующий путь к БД в TIBDataBase. Указываю неверный логин или верный логин, но неверный пароль и мне ошибка класса EIBDataBaseError, но текст сообщения уже другой! Текст такой: 'Your user name .... are not defined. ...'.

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

              ExpandedWrap disabled
                        try
                        IBDataBase.Connected:=true;
                        except
                          on E : что здесь должно быть, чтобы определить 1-й случай? do begin
                             sShowMessage('несуществующий путь бд!');
                             exit;
                             end;
                 
                          on E : что здесь должно быть, чтобы определить 2-й случай? do begin
                             sShowMessage('неверный пользователь или пароль');
                             exit;
                             end;
                 
                          on E : Exception do begin //люая другая ошибка
                             sShowMessage(e.ClassName,E.Message+' совершенно другая ошибка');
                             exit;
                             end;
                          end;

              Помогите разобраться пожалуйста, я очень хочу сделать так, но не знаю.
                Цитата Continental @
                Так вот я хочу сказать, что в двух случаях ошибки совсем разные, а вот класс исключения один и тот же.

                Если у вашего EIBDataBaseError нет какого-нибудь IBErrorCode - то это криво спроектированные классы Interbase.

                Цитата Continental @
                Так я не могу понять, как же мне отловить первую ошибку, или вторую вот с помощью такой конструкции:

                Если никакого поля с кодом нет, то по-хорошему - никак.

                (Т.е. вы можете, конечно, попробовать анализировать сообщение, но ведь его могут локализовать).

                Добавлено
                P.P.S.
                Если же поле кода есть, то в общем случае как-то так:
                ExpandedWrap disabled
                  try
                    IBDataBase.Connected:=true;
                  except
                    on E: EIBDataBaseError do
                      if E.ErrorCode = XXX then
                      begin
                        sShowMessage('несуществующий путь бд!');
                        exit;
                      end
                      else
                      if E.ErrorCode = YYY then
                      begin
                        sShowMessage('неверный пользователь или пароль');
                        exit;
                      end
                      else
                        raise;
                  end;


                Добавлено
                Или:
                ExpandedWrap disabled
                  try
                    IBDataBase.Connected:=true;
                  except
                    on E: Exception do
                    begin
                      if E is EIBDataBaseError then
                      begin
                        if EIBDataBaseError(E).ErrorCode = XXX then
                        begin
                          sShowMessage('несуществующий путь бд!');
                          exit;
                        end
                        else
                        if EIBDataBaseError(E).ErrorCode = YYY then
                        begin
                          sShowMessage('неверный пользователь или пароль');
                          exit;
                        end;
                      end;
                   
                      ShowMessage(e.ClassName,E.Message+' совершенно другая ошибка');
                    end;
                  end;


                Добавлено
                P.P.P.S. Но в общем и целом, если вам это нужно только для показа сообщения об ошибке "на русском", то лучше бы вам локализовать константы вместо того, чтобы ставить кучу обработчиков по всей программе.
                  Цитата CodeMonkey @
                  Если у вашего EIBDataBaseError нет какого-нибудь IBErrorCode

                  Именно так это свойство и называется, что нетрудно узнать из хелпа (который надеется на длительное и плодотворное сотрудничество с Continental :) )
                  Значения этих кодов прописаны в файле IBErrorCodes.pas (ищи его где-нибудь в C:\Program Files\Borland\Delphi7\Source\Vcl\IBErrorCodes.pas, к примеру)
                    С облегчением ... :)
                    ExpandedWrap disabled
                              try
                              Connected:=true;
                              except
                                on E : EIBInterBaseError do begin
                                   sShowMessage(IntToStr(e.IBErrorCode),E.Message);
                                   exit;
                                   end;

                    Спасибо всем, что открыли глаза.

                    Добавлено
                    О! вообще круто! CodeMonkey, спасибо что подсказали вот это
                    ExpandedWrap disabled
                      except
                        on E: Exception do
                        begin
                          if E is EIBDataBaseError then
                          begin
                            if EIBDataBaseError(E).ErrorCode = XXX then

                    Я теперь это заделал в applicationevents. Теперь у меня будет и лог вестись и сообщения об ошибках выводится! Е-Е-Е!
                      Для лога ошибок имеет смысл использовать хук на исключения. См. JCL, EurekaLog, madExcept. Помимо сообщения этот способ позволит получить стек вызовов и состояние процессора в момент ошибки. С этой информацией зачастую продиагностировать ошибку можно даже не запуская отладчик.
                      1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0609 ]   [ 15 queries used ]   [ Generated: 20.06.25, 06:12 GMT ]