Delphi - How to handle multiple except types

I'm willing to handle some errors with a specific function and some other with another function. Is there a way to do that in Delphi without repeating the whole 'on E:X do' block?

For instance, I have the following code:

try
  someProcedure()
except
  on E:Error1 do
    thisFunction(E)
  on E:Error2 do
    thisFunction(E)
  on E:Exception do
    thatFunction(E)
end;

Could it be written in any way similar to the following, avoinding the repetition of thisFunction?

try
  someProcedure()
except
  on E:Error1, Error2 do
    thisFunction(E)
  on E:Exception do
    thatFunction(E)
end;

Upvotes: 2

Views: 897

Answers (1)

Andreas Rejbrand
Andreas Rejbrand

Reputation: 108929

No, that syntax is not possible, as you can see in the documentation. This restriction is actually reasonable. Indeed, if such syntax were allowed, what type would the E variable have?

However, you can use class hierarchies to achieve the same effect. (If you have control over the exception classes, that is. And if it makes sense logically.)

For instance, if

type
  EScriptException = class(Exception);
    ESyntaxError = class(EScriptException);
    ERuntimeError = class(EScriptException);
      EDivByZeroError = class(ERuntimeError);
      EAverageOfEmptyList = class(ERuntimeError);

then

try

except
  on E: ESyntaxError do
    HandleSyntaxError(E);
  on E: EDivByZeroError do
    HandleRuntimeError(E);
  on E: EAverageOfEmptyList do
    HandleRuntimeError(E);
end;

can be written

try

except
  on E: ESyntaxError do
    HandleSyntaxError(E);
  on E: ERuntimeError do
    HandleRuntimeError(E);
end;

If you cannot structure your exception classes like this (or if it doesn't make sense logically), you can of course do something along the lines of

try

except
  on E: ESyntaxError do
    HandleSyntaxError(E);
  on E: Exception do
    if (E is EDivByZeroError) or (E is EAverageOfEmptyList) then
      HandleRuntimeError(E);
end;

In fact, if you like, you can catch an exception of the Exception base class and get full programmatic control over the handling:

try

except
  on E: Exception do
    if E is ESyntaxError then
      HandleSyntaxError(E)
    else if (E is EDivByZeroError) or (E is EAverageOfEmptyList) then
      HandleRuntimeError(E)
    else
      raise;
end;

(But beware: what happens if you add a trailing semicolon to the line before the last else?)

Upvotes: 6

Related Questions