M Y D E L P H I 7 . R U Самоучитель программирования  
 
  • Главная
  •  

     

    Протоколирование исключительных ситуаций

    Часто нужно иметь подробный материал для анализа причин возникновения ИС. Разумно было бы записывать все данные о них в файл, чтобы потом прогнозировать ситуацию. Такой подход важен для программ, которые так или иначе будут отчуждены от разработчика: в случае возникновения непредвиденной ситуации это позволит ответить на вопросы "кто виноват?" и "что делать?". В следующем примере предложен вариант реализации протоколирования ИС.

    const LogName : string = 'c:\appexc.log';

    procedure LogException;

    var fs: TFileStream; m : word;buf : array[0..511] of char;

    begin

    if FileExists(LogName) then m := fmOpenReadWrite else m := fmCreate;

    fs := TFileStream.Create(LogName,m);

    fs.Seek(0,soFromEnd);

    StrPCopy(Buf,DateTimeToStr(Mow)+' . ');

    ExceptionErrorMessage

     (ExceptObject,ExceptAddr,@buf[StrLenfbuf)],

    SizeOf(Buf)-StrLen(buf));

    StrCat(Buf,#13#10);

     fs.WriteBuffer (Buf, StrLer. ;buf) ) ;

     fs.Free;

     end;

    procedure TForml.ButtonlClick(Sender: TObject);

    var x,y,z: real;

    begin

    try

    try

    x:=1.0;y:=0.0;

    z := x/y;

    except

    LogException;

     raise;

    end; 

    except

    on E:EIntError do ShowMessage('IntError');

    on E:EMathError do ShowMessage('MathError');

     end;

     end;

    Здесь задачу записи информации об ИС решает процедура LogException. Она открывает файловый поток и пишет туда информацию, отформатированную При помощи уже упоминавшейся функции ExceptionErrorMessage.

    В качестве ее параметров выступают значения функций Exceptobject и ExceptAddr. К сформированной строке добавляется время возникновения ИС. Для каждого защищаемого блока кода создаются две вложенные конструкции try. .except. Первая, внутренняя — для вас; в ней ИС протоколируется и продвигается дальше. Внешняя — для пользователя; именно в ней проводится анализ типа ИС и готовится сообщение.

    В Object Pascal существует и расширенный вариант употребления оператора

    raise:

    raise окземпляр объекта типа Exception> [at <адрес>]

    Естественно, объектный тип должен быть порожден от Exception. To, что в таком типе ничего не переопределено, не столь важно — главное, что в обработчике ИС можно отследить именно этот тип.

    ELoginError = class (Exception);

    If LoginAttemptsNo > MaxAttempts then raise ELoginError.Create('Ошибка регистрации пользователя');

    Конструкция at <адрес> используется для того, чтобы изменить адрес, к которому привязывается возникшая ИС, в пределах одного блока обработки ИС.