9

I don't want to catch generic exceptions, but I want to handle all the exceptions I want to catch exactly the same way.

For arguments sake, lets say the code is:

try {
   doSomething();
}
catch(AException ex) {
   handleException();
}
catch(BException ex) {
   handleException();
}
catch(CException ex) {
   handleException();
}
/* ... */
catch(ZException ex) {
   handleException();
}

Is there an elegant way to express this?

I thought about creating a variable

Set<Type> exceptionsToHandle = new Set<Type>{
   AException.class, 
   BException.class, 
   CException.class, 
   /* ... */
   ZException.class 
}
try {
   doSomething();
}
catch(Exception ex) {
  if (exceptionsToHandle.contains(getType(ex)) {
       handleException();
  }
  else {
      throw ex;
  }
}

Except there is a fundamental problem: We have no way to actually get the exception's Type outside of ugly trial and error code which will be as inelegant as the problem I'm trying to solve.

Alternatively, I could make a set of strings and then check the class name for the instance of the Exception, but I'd rather have a typesafe solution.

Any ideas?

  • getTypeName won't work for you? – Girbot Apr 12 '18 at 11:50
  • @Girbot, I'd rather a typesafe solution, so I want the Type, not a string of its name. – Brian Kessler Apr 12 '18 at 12:09
  • @BrianKessler Did you check my answer already. Should be a solution. Hope you find it more elegant than the standard code. – Robert Sösemann Apr 12 '18 at 20:11
  • 1
    @BrianKessler you should also have a look at this similar Java question and how it uses polymorphism in the handle methods: stackoverflow.com/questions/13112976/… – Robert Sösemann Apr 13 '18 at 14:56
  • 1
    @RobertSösemann, thanks for the response, but that wasn't really what I was looking for. Adrian Larson's answer below was exactly what I wanted. That said, your link has useful and interesting information... I'd scratched my head over similar issues in the past. – Brian Kessler Apr 13 '18 at 20:04
7

You can still support concrete types with getTypeName by using the Type.forName method.

Set<Type> whilelist = new Set<Type> { DmlException.class, ListException.class };
try
{
    // do stuff
}
catch (Exception pokemon)
{
    if (!whitelist.contains(Type.forName(pokemon.getTypeName()))
    {
        throw pokemon;
    }
    // actual error handling logic here
}
  • This is what I was looking for, cheers! – Brian Kessler Apr 13 '18 at 19:55
3

It's doable with an abstract base class as shown below.

public abstract class CustomException extends System.Exception {

}

Implementing exception classes

public class AException extends CustomException {

}


public class BException extends CustomException {

}

This test proves that it works

@IsTest
private class CustomException_Test {

    @IsTest
    private static void genericHandling() {

        Boolean aCatched = false;
        Boolean bCatched = false;
        Boolean othersIgnored = true;

        try {
            throw new AException();
        }
        catch(CustomException cex) {
            aCatched = true;
        }

        try {
            throw new BException();
        }
        catch(CustomException cex) {
            bCatched = true;
        }

        try {
            throw new NotACustomException();
        }
        catch(CustomException cex) {
            othersIgnored = false;
        }
        catch(Exception ex) {
            othersIgnored = true;
        }

        System.assert(aCatched);
        System.assert(bCatched);
        System.assert(othersIgnored);
    }
}
  • 1
    Very creative. I like it! Doesn't work if any of the exception types you want to catch are standard though. – Adrian Larson Apr 12 '18 at 23:04
  • True. But then he could use Polymorphism. Provide a version of handleException(Type ex) for each required type and one for generic Exceptions that basically does nothing. – Robert Sösemann Apr 13 '18 at 14:54
  • 1
    Good answer. I thought to do something similar with interfaces, but SFDC wouldn't seem to let an Exception implement anything. Also, as @Adrian Larson observed, it can be a problem if I want to catch some standard exceptions, or similarly if I have Exceptions which are already extending some other base since Apex doesn't allow multiple inheritance. – Brian Kessler Apr 13 '18 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.