Как записать исходную строку, вызывающую исключение, и добавить пользовательскую информацию? - PullRequest
4 голосов
/ 04 августа 2011

Наше приложение регистрирует исходную строку, вызывая исключение с JCL, и это прекрасно работает. Я использую D2007. У меня есть событие TApplicationEvents.OnException, которые делают фактическое ведение журнала. Учтите это:

function MyFunc: String;
begin
  // Codelines that may raise exception.
  // Call functions that also may raise exception  
end;

procedure ComplexFunc(aVariable: String);
begin
  // also here can it be exceptions....
  // Code here that is the cause of exception
end;

procedure foo;
var
  myVar: String;
begin
  myvar := MyFunc;
  ComplexFunc(myvar);  
end;

procedure TMainForm.ApplicationEvents1Exception(Sender: TObject; E: Exception);
begin
  LogLastException(E, 'Unhandled Exception (%s)', [E.Message], 20);
end;

У меня есть 3 метода и мое событие onException. LogLastException регистрирует стек вызовов при возникновении исключения. Проблема в том, что я не могу добавить информацию в E.Message без потери исходной строки, которая вызывает исключение. Представьте, что это вторая строка в ComplexFunc, которая вызывает исключение. Я также хочу записать значение переменной myvar. Поэтому я изменяю код на:

function MyFunc: String;
begin
  // Codelines that may raise exception.
  // Call functions that also may raise exception  
end;

procedure ComplexFunc(aVariable: String);
begin
  // also here can it be exceptions....
  // Code here that is the cause of exception
end;

procedure foo;
var
  myVar: String;
begin
  try
    myvar := MyFunc;
    ComplexFunc(myvar); 
  except
    on E: Exception do
      raise TException.CreateFmt('myvar = %s', [myvar]);
  end; 
end;

procedure TMainForm.ApplicationEvents1Exception(Sender: TObject; E: Exception);
begin
  LogLastException(E, 'Unhandled Exception (%s)', [E.Message], 20);
end;

Теперь записывается значение myvar, НО по цене я теряю исходную линию исключения. Вместо этого регистрируется строка с повышением TException.CreateFmt. Любое предложение о том, как сделать оба?

Привет

Ответы [ 5 ]

5 голосов
/ 04 августа 2011

В дополнение к ответу Марьян Веннема (за которым я последую) вы можете поднять новое исключение и сделать так, чтобы оно выглядело так, как будто оно пришло с адреса старого исключения.

except
  on E: Exception do
    raise Exception.CreateFmt('myvar = %s', [myvar]) at ExceptAddr;
end;
3 голосов
/ 04 августа 2011

Вы теряете исходную строку источника исключения, потому что

  except
    on E: Exception do
      raise TException.CreateFmt('myvar = %s', [myvar]);
  end; 

эффективно обрабатывает исходное исключение (убирает его) и вызывает новое.Который, конечно, тогда будет иметь свою собственную «исходную строку исключения». Решение

@ balazs сохраняет исходную строку исходного исключения в сообщении нового исключения.Решение Стефана близко к тому, которое я бы использовал.К сожалению, он заменяет исходное сообщение только значением myvar.Я хотел бы добавить строку поверх исходного сообщения, а затем просто повторно вызвать исключение:

except
  on E: Exception do
  begin
    E.Message := Format('%s'#13#10'%s', [Format('MyVar: %s', [MyVar]), E.Message]);
    raise;
  end;
end; 
2 голосов
/ 04 августа 2011

Я пробовал что-то подобное?

 try    
    myvar := MyFunc;    
    ComplexFunc(myvar); 
 except
    on E: Exception do
    begin
      e.message := format('myvar = %s', [myvar]);
      raise ;
    end; 
  end;
1 голос
/ 04 августа 2011

Я не знаю, что делает LogLastException, но если вы можете перенаправить его результат в строку, а не в журнал, вы можете переопределить исключение следующим образом:

  except
    on E: Exception do
    begin
      str := LogLastExceptionToString(E, 'Unhandled Exception (%s)', [E.Message], 20);  
      raise TException.CreateFmt( str + 'myvar = %s message so far:' , [myvar]);
    end; 
  end;
0 голосов
/ 04 августа 2011

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

...