4

It's come to my attention that you can use System.assert(), System.assertEquals(), etc. outside of test classes in Apex.

I've seen a lot of custom Exception classes written that do nothing but extend the Exception class, and a lot of Apex production (i.e. non-test) code that looks more or less like this:

public class MyClass {

  public class MyException extends Exception {}

  public static Account getAccount(Id accountId) {
    List<Account> accounts = 
      [SELECT Name FROM Account WHERE Id = :accountId];
    if (accounts.size() != 1) {
      throw new MyException(
        'Did not find an account for Id ' + accountId
      );
    }
    // ...
  }
}

This is less code, and cleaner in my opinion:

public class MyClass {

  public static Account getAccount(Id accountId) {
    List<Account> accounts = 
      [SELECT Name FROM Account WHERE Id = :accountId];
    System.assertEquals(
      1, 
      accounts.size(), 
      'Did not find an account for Id ' + accountId
    );
    // ...
  }
}

I know the below approach is going to throw an AssertException, whereas you can give the exception whatever name you want in the above approach. But the name of the exception class itself seems pretty unimportant -- way less important than the message, which you can customize either way.

Are there any other drawbacks to the System.assert... approach that I'm neglecting?

4

Outside of absuing the functionality a little...

  • Using system.assert() doesn't really save much in terms of typing or lines of code (5 lines vs 6 lines in your example, counting the lines with closing braces/parens)
  • Only works well for relatively simple comparisons (it's not going to be making a long or highly nested set of conditions any shorter)
  • Would prevent you from being able to have multiple catch blocks to distinguish between different exception types (you aren't doing the pokemon catch, catch(Exception e), i.e. gotta catch 'em all, are you?)
  • Doesn't contain the name of the class unless you look at the stack trace (which needs to be fetched using .getStackTraceString())

I think that having the exception name is worth a bit more than you give it credit for. In the email you (or someone) would get, or in the log, a good exception class name can immediately tell you which class to start digging into without needing to look for the stack trace.

  • Thanks, Derek, good points! A few counterargs: 1. For the parts that differ, the System.assert() approach is less than half the number of characters (58 chars less), even if it is close to the same number of lines. 2. Even on a complex comparison, you do still save 58 chars. 3. OK, but I rarely see multiple custom exception classes implemented in the same parent class that would allow for a distinction based on class, and 4. I can't really imagine not wanting to look at a stack trace when I see an exception. They're so helpful! Why wouldn't you? – Matthew Souther Nov 23 '20 at 20:01
  • 2
    @MatthewSouther Stack traces are immensely helpful, but not always present. I haven't dug into the conditions where it happens, but I do get exception emails that contain no stack trace (and no relevant record ids either). I suppose one thing I missed was that using assertions is nonstandard and would violate the principle of least surprise. The extra typing shouldn't be that burdensome if you have any form of autocomplete/code completion. – Derek F Nov 23 '20 at 20:14
  • 2
    Also -- the SFDC runtime system throws specific exceptions - QueryException, DMLException, etc. There are advantages to having one's custom code follow SFDC practice for understandability. And ... explicit exception types lend themselves to more readable unit tests and even mockable exceptions (when using StubAPI or ApexMocks) – cropredy Nov 23 '20 at 20:20

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.