Nested Exception

delphi package - automated exception handling
Vitalik
Posts: 12
Joined: Tue Oct 27, 2009 8:38 pm

Re: Nested Exception

Post by Vitalik »

Let me explain with an example

Here are exception classes I'm going to use:

Code: Select all

ESQLException = class(ExceptionFields)
public
  constructor Create(const Msg, SQL: string); overload;
  constructor Create(AExceptObject: TObject; const SQL: string); overload;
end;

constructor ESQLException.Create(const Msg, SQL: string);
begin
  inherited Create(Msg);
  AddValue('SQL', SQL); // method from ExceptionFields
end;

constructor ESQLException.Create(AExceptObject: TObject; const SQL: string);
begin
  if (AExceptObject <> nil) and (AExceptObject is Exception) then
    Create((AExceptObject as Exception).Message, SQL)
  else
    Create('Unknown SQL exception!', SQL);
end;
And another class:

Code: Select all

EDivPrescriptionNotFound = class(ExceptionFields)
public
  constructor Create(const Msg: string; const DPIDGUID: TGUID);
end;

constructor TComplexDrugPrescriptionControllerPostgreSQL.EDivPrescriptionNotFound.Create(
  const Msg: string; const DPIDGUID: TGUID);
begin
  inherited Create(Msg);
  AddValue('DPIDGUID', DPIDGUID.ToString);
end;

And the place where exception occures:

Code: Select all

try
  ds.Open; // TADODataSet
  DPIDGUID := TGuidField(ds.FieldByName('DPID')).AsGuid;
  if FindByDPID(CDP, DPIDGUID, DP) then
  begin
    // normal work
  end
  else
    raise EDivPrescriptionNotFound.Create('Divided prescription wasn''t found!', DPIDGUID); // For this exception the DPIDGUID parameter is important and should be placed into bug report fields
  ds.Next;
except
  Exception.RaiseOuterException(ESQLException.Create(ExceptObject, SQL)); // For ESQLException the key parameter is SQL, but I also don't want to lose DPIDGUID from EDivPrescriptionNotFound
end;

And here is an exception handler which I registered with RegisterExceptionHandler:

Code: Select all

function StoreReportToFile(const exceptIntf: IMEException;
  const ReportPath: string): string;
begin
  if exceptIntf.ExceptObject is ExceptionFields then
    AddFieldsToBugReport(exceptIntf.ExceptObject as Exception, exceptIntf.BugReportHeader);
end;

procedure AddFieldsToBugReport(E: Exception; BugReportHeader: IMEFields);
begin
  if E is ExceptionFields then
    ExceptionFieldsToBugReport(E as ExceptionFields, BugReportHeader);

  if E.InnerException <> nil then
    AddFieldsToBugReport(E.InnerException);
end;

procedure ExceptionFieldsToBugReport(E: ExceptionFields; BugReportHeader: IMEFields);
var
  Field: string;
  Value: string;
begin
  try
    for Field in e.Fields do
      if e.GetValue(Field, Value) then
        BugReportHeader.Add(Field, Value);
  except
  end;
end;

duncan
Posts: 3
Joined: Thu Aug 02, 2018 5:14 am

Re: Nested Exception

Post by duncan »

We have a case were we throw a new exception from within an except block (via Exception.RaiseOuterException), but still need to know what the inner exception is.

Is there a chance we can get this bug fixed?
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: Nested Exception

Post by madshi »

I'm scared about changing this because it's been working very stably for many years. But I guess I could add an option to change the behaviour. Can you please a simple test project that shows what you need and that it's not working with madExcept enabled (but working with madExcept disabled)?
Post Reply