[fpc-pascal] FPCUnit test + raise E;

Marcos Douglas md at delfire.net
Tue Sep 17 17:18:55 CEST 2013


On Sun, Sep 15, 2013 at 4:25 PM, Sven Barth <pascaldragon at googlemail.com> wrote:
> On 15.09.2013 13:05, Marcos Douglas wrote:
>>
>> [[cut]]
>>
>>
>> I tried. No makes difference.
>> (could you explain which the difference to call "raise" using "raise E
>> at [...]"?)
>
>
> The raise-at statement allows you to raise an exception for a specific
> address. This allows you to have e.g. a error handling procedure (to wrap a
> more compilated generation of a exception class) but have the exception
> address still point to the original call site. E.g.:
>
> === code begin ===
>
> procedure Error(aArg: Boolean);
> begin
>   if aArg then
>     raise Exception.Create('Test')
>   else
>     raise Exception.Create('Test') at get_caller_addr(get_frame),
> get_caller_frame(get_frame);
> end;
>
> procedure Test1;
> begin
>   Error(True);
> end;
>
> procedure Test2;
> begin
>   Error(False);
> end;
>
> begin
>   try
>     Test1;
>   except
>     DumpExceptionBackTrace(Output);
>   end;
>   try
>     Test2;
>   except
>     DumpExceptionBackTrace(Output);
>   end;
> end;
>
> === code end ===
>
> In case one the stack trace will contain Test1 and Error in case two the
> stack trace will be only Test2.

Ok, thanks for the explanation!


>> I implemented -- but not up to Git yet -- some like that:
>> procedure TghSQLHandler.DoOnException(E: Exception);
>> var
>>    NewEx: EghSQLError;
>> begin
>>    if Assigned(FOnException) then
>>      FOnException(Self, E)
>>    else
>>    begin
>>      NewEx := EghSQLError.Create(Self, E.Message);   // <<<
>>      NewEx.InnerException := E;                                  // <<<
>>      raise NewEx;
>>    end;
>> end;
>>
>> So, if I recreate the Exception, it works in any cases. As you see, I
>> created a new property (InnerException) to save the original
>> exception to know what the real Exception happened...
>> But I think this introduces much more overhead to processing.
>
>
> Can you access fields of the InnerException? Maybe it's a problem of
> reraising an existing exception...

Yes, I have access but no, this is not the problem. I had coded
InnerException property after the problem to solve it, creating a new
Exception but not missing the original one.


>> In my code I have classes that inherited from TghSQLHandler. This
>> class have the DoOnException method.
>> So DoOnException can be call many times in override methods. Maybe the
>> program "broke" the stack because "raise E" can be call and raise an
>> exception; the next "level" raise another; and next call again.  :/
>
>
> Could possibly be. If you could reproduce it in an as simple example as
> possible that would help.


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
In attachment.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!



> Another thing you could try (just for testing): change your exception
> handler procedure to a function that returns bool and use it like this:
>
> === code begin ===
>
>
> procedure TghSQLConnector.Connect;
> begin
>   try
>     FLib.Connect;
>   except
>     on E: Exception do
>       if not DoOnException(E) then
>         raise;
>   end;
> end;
>
> === code end ===
>
>
> Regards,
> Sven

The only difference is the use of raise; instead raise E; right?

Marcos Douglas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: project1.zip
Type: application/zip
Size: 2478 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20130917/f264ee15/attachment.zip>


More information about the fpc-pascal mailing list