Reputation: 1967
I was wondering if there are exceptions/errors, which do make your code jump into an except block but aren't handled by E : exception.
try
i := StrToInt(s);
{...do a lot more...}
except
on E : EConvertError do begin
ShowMessage('You need to input a valid number.');
end;
on E : Exception do begin
ShowMessage('Something went wrong.');
Raise;
end;
end;
Is there a way that a program could have an error that would ignore both statements in this except block? Or should I do it like this :
try
i := StrToInt(s);
{...do a lot more...}
except
on E : EConvertError do begin
ShowMessage('You need to input a valid number.');
end;
else begin // swapped on e : Exception with else
ShowMessage('Something went wrong.');
Raise;
end;
end;
Upvotes: 3
Views: 489
Reputation: 613461
You can throw anything that derives from TObject
. In order to catch every such class you'd need to specify TObject
in your on
statement.
From the documentation:
Exception types are declared just like other classes. In fact, it is possible to use an instance of any class as an exception, but it is recommended that exceptions be derived from the SysUtils.Exception class defined in SysUtils.
In reality I know of no code that throws anything that does not derive from Exception
, although @TLama points out one example in a legacy deprecated VCL class in the comments. Certainly StrToInt
only throws Exception
descendents.
If you don't need to access the exception object you can use a plain except
clause without an on
statement.
try
....
except
// deal with all exceptions
end;
Or you can use the else
clause of an on
statement as a catch all, again you won't get immediate access to the exception object.
Otherwise you can specify a base class for the exceptions that you wish to catch. For instance on E: TObject
catches everything derived from TObject
.
So, as we see, it is possible that things not derived from Exception
may be thrown. But you must ask yourself if your code ever does that? If not then it makes most sense to test for Exception
in your catch all handlers. That will give you access to the members of Exception
. Of course, one does wonder why you have a catch all exception handler. Their existence are often indication of poor design.
Continuing the theme of StrToInt
, you only need to catch EConvertError
. That's what is raised when the conversion fails. You should ignore any other exception class as, in your example, the code won't know what to do with anything else. One of the goals of writing exception handling code is to handle what you know how to deal with, and ignore everything else.
In fact, TryStrToInt
is what you need here:
if TryStrToInt(s, i) then
// do stuff with i
else
// deal with conversion error
This obviates the need to handle any exceptions and makes your code far more readable.
I know that StrToInt
is just an example, but it serves quite well to demonstrate the benefits of trying to avoid handling exceptions.
Upvotes: 7