Re: Handling exceptions in functions
- From: Chris Morgan <chris.nospam@xxxxxxxxxxxxxx>
- Date: Mon, 28 May 2007 14:07:04 +0100
Hi there
I was wondering if there's a better way to handle exceptions in functions calls.
What I would like to achieve is trivial, if any error happens in the function,
returns false and raise the exception, otherwise return true.
This cannot happen - you cannot return a value *and* raise an exception.
You have to do one or the other. Raising an exception (or not catching
an exception which occurs during the course of your function) means the
function will not return a value.
// This is just a sample. It can be any kind of exception.
procedure DoSomething( aParam : Integer );
begin
if aParam=0 then Raise Exception.Create('Something terrible happened!');
end;
OK, this is valid.
//# no hints; works fine but I cannot trap the error;
function TMyObject.MyFunction( aParam1, aParam2 : Integer ) : Boolean;
begin
try
DoSomething( aParam1 );
DoSomething( aParam2 );
Result := True;
except
Result := False;
end;
end;
This should work using the DoSomething function defined above - are you sure you are not seeing the IDE intercept your exception during
debugging? This is normal, but can be turned off in the debugging
options (something like Tools-Options-Debugger in the Delphi menu).
Run your exe outside the Delphi IDE, does it now appear to work as you
think it should?
// I suspect this one will return anything on error
function TForm1.MyFunction( aParam1, aParam2 : Integer ) : Boolean;
begin
Result := False; //# Hint : Value assigned never used
try
DoSomething(aParam1);
DoSomething(aParam2);
Result := True;
except
Raise;
end;
end;
This is pointless. It just re-raises any exception which has already
been raised.
// I suspect this one will return anything on error
function TMyObject.MyFunction2( aParam1, aParam2 : Integer ) : Boolean;
begin
try
DoSomething( aParam1 );
DoSomething( aParam2 );
Result := True;
except
on E:Exception do begin
Result := False; // #Hint: Value assigned never used
Raise;
end;
end;
end;
Again, this is pointless, and the hint is correct.
Raising an exception (or letting exceptions escape from your function,
means the return value will not be set, or used, by the calling
function.
//# no hints, but never passes by Result := False;
//# No warnings too... Shouldn't this be a bug?
function TMyObject.MyFunction3( aParam1, aParam2 : Integer ) : Boolean;
begin
try
DoSomething( aParam1 );
DoSomething( aParam2 );
Result := True;
except
on E:Exception do begin
Raise;
Result := False;
end;
end;
end;
Same as above.
//This one returns always true
function TMyObject.MyFunction4( aParam1, aParam2 : Integer ) : Boolean;
begin
Result := True;
try
DoSomething( aParam1 );
DoSomething( aParam2 );
except
on E:Exception do begin
Result := False; // #Hint: Value assigned never used
Raise;
end;
end;
end;
Same as above.
// Works fine, but I have to pass one extra parameter.
// Some functions are using one of the above "templates", and changing
// all of them to meet this one will really be my last resource. A lot of
// callers depends on trapping exceptions, and using the method below, no more
// exceptions will raise. You might guess I won't sleep for sometime.
// Before start changing, I thought to post here and hope someone can shed some
// light.
function TMyObject.MyFunction5(aParam1, aParam2: Integer;
var aErrMsg: String): Boolean;
begin
try
DoSomething(aParam1);
DoSomething(aParam2);
Result := True;
except
on E:Exception do begin
Result := False;
aErrMsg := E.Message;
end;
end;
end;
This is valid.
How you want to handle exceptions depends completely on what you
want your code to do. Exceptions are designed to allow programs
to cope with expected and unexpected errors.
So, for example, expected errors in a program may be (for example)
Disk full.
Read-only file, can't save
etc...
Unexpected errors are, well, unexpected!
With the expected errors, you can use the exception handler to
catch and deal with those errors (for example, for a read-only file,
let the user select another file), and let unhandled errors
escape to a higher level of your program, since you cannot
realistically do anything to fix the error.
So ideally, your exception handlers should look something like this:
try
...
except
on EDiskFullError do begin
// expected error - handle here
end
on EReadOnlyFile do begin
// another expected error - do something else
end
else raise; // unexpected errors - can't fix these
Hope this helps.
Cheers,
Chris
.
- Follow-Ups:
- Re: Handling exceptions in functions
- From: Thomas Mueller
- Re: Handling exceptions in functions
- From: Clément Doss
- Re: Handling exceptions in functions
- References:
- Handling exceptions in functions
- From: Clément Doss
- Handling exceptions in functions
- Prev by Date: Re: Delphi 2007 Review
- Next by Date: Re: Debug issues
- Previous by thread: Re: Handling exceptions in functions
- Next by thread: Re: Handling exceptions in functions
- Index(es):
Relevant Pages
|
Loading