Иллюстрированный самоучитель по Delphi 7 для профессионалов

Коды ошибок в исключительных ситуациях

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

Ошибкам, возникающим в нем. Сообщение типа "Exception EZeroDivide in module MyNiceProgram at addr $0781BABO" годится для разработчика, пользователя же оно повергнет в полный ступор. Если он позвонит в вашу службу техподдержки, то, скорее всего, не сможет ничего объяснить. Гораздо грамотнее дать ему уже "разжеванную" информацию и, в том числе, числовой код.

Один из путей решения этой проблемы – размещение сообщений об ошибках в ресурсах программы. Если же вы еще делаете и несколько национальных версий программы на разных языках, то этот путь – единственный.

"Классический" способ поместить текст в файл ресурсов – 3-этапный:

  1. Создается исходный файл ресурсов с расширением гс, в который помещаются необходимые строки с нужными номерами.
  2. Файл обрабатывается компилятором ресурсов brcc32.exe (находится в папке bin в структуре папок Delphi). На выходе образуется одноименный файл с расширением res.
  3. Файл включается в программу указанием директивы $R, например:
{$R mystrings.res}.

Чтобы совместно использовать константы-номера ошибок в файле ресурсов и в коде на Delphi, вынесем их в отдельный включаемый файл с расширением .inc:

const
IOError = 1000;
FileOpenError = IOError + 1;
FileSaveError = IOError + 2;
InternetError = 2000;
NoConnecticnError = InternetError + 1;
ConnectionAbortedError = InternetError + 2;

Взглянув на файл, вы увидите, что ошибки в нем сгруппированы по категориям. Советуем вам поступить так же, разделив константы категорий промежутком в 1000 или даже 10 000.

Сам файл ресурсов может выглядеть так:

#include "strids.inc" STRINGTABLE
{
FileOpenError, "File Open Error"
FileSaveError, "File Save Error"
NoConnectionError, "No Connection"
ConnectionAbortedError, "Connection Aborted"
}

"Вытащить" строку из ресурсов можно несколькими способами, но самый простой из них – просто по числовому идентификатору, переданному в функцию Loadstr (модуль SysUtils). Код:

ShowMessage(LoadStr(NoConnectionError));

Покажет сообщение "NO connection".

Если же строка используется при возбуждении ИС, то место идентификатору-в перекрываемом конструкторе Exception.createRes, один из вариантов которого работает подобно функции Loadstr:

if FileOpent'c:\myfile.txt", fmOpenRead) = INVALID_HANDLE_VALUE then
raise EMyException.CreateRes(FileOpenError);

Таким образом, решена половина проблемы: возможным исключительным ситуациям присвоены номера, им в соответствие поставлен текст. Теперь о второй половине – как в обработчике ИС этот номер использовать.

Ясно, что нужно объявить свой класс ИС, включающий в себя свойство-код ошибки.

EExceptionWithCode = class(Exception)
private
FErrCode: Integer;
public
constructor CreateResCode(ResStringRec: PResStringRec);
property ErrCode: Integer read FErrCode write FErrCode;
end;

Тогда любой обработчик сможет к нему обратиться:

if E is EExceptionWithCode then
ShowMessage('Error code: ' + IntToStr(EExceptionWithCode(E).ErrCode) +
#13*10
+ 'Error text: ' + E.Message);
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.