Why have private properties in an exception class that has only a constructor

apex

I'm reading through an open source project to learn Apex more deeply. It's a widely used project and has some code that looks like this:

public class BaseException extends Exception {
    protected MyType my;
    protected OtherType other;
}

public class MyException extends BaseException {
    private ThirdType third;
    private MyException(
        MyType my,
        OtherType other,
        ThirdType third
) {
    this.my = my;
    this.other = other;
    this.third = third;
    String msg;
    if (my == 'foo') {
        msg = 'one {0}';
    } else if (my == 'bar') {
        msg = 'two {0}';
    } else if (my == 'bas') {
        msg = 'three {0}';
    }
    this.setMessage(
        String.format(
            msg,
            new List<String>{
                other.name();
                third.name();
            }
        )
    );
}

What purpose does having the protected and private properties? I get that we get some inheritance here, but they aren't referenced after they're set, there are no other methods in the classes that refer to them, and since they're private/protected, no outside object can reference them.

This code is from people who know way more about Apex than I do, so I'm assuming there's a reason.

Best Answer

This coding approach doesn't strike me as something that's Salesforce or Apex specific, but rather something that you'd be likely to see in basically any Object-Oriented language. Looking at custom exception classes is probably not the best way to get a feel for what's going on, but let's continue.

Aside from the fact that public and protected class variables are inherited by subclasses (thus making code being slightly less repeated), I suspect the driving force here might simply be:

  • That could be part of the code style that the developers/maintainers decided to use
  • Documentation, IDEs, and static analysis tools can generally pull method names and class-level variables from classes

VisualStudio Code, for example, has an "Outline" section in its file explorer that makes it easy to see (and jump to) class-level variables and methods. Even if things aren't explicitly used elsewhere, they can still act as some self-documentation.

Private variables give you strict control over what code can set/modify it. In MyException, the third variable can be set by calling the constructor. Classes that extend MyException could still call super(myTypeInstance, otherTypeInstance, thirdTypeInstance); in their constructors to take advantage of whatever work MyException does (again, re-use code and keep it DRY (don't repeat yourself) ).

Contrary to your claim, MyException does make use of its inherited and private variables after they've been set. One of them is being used to determine which of several error message templates to use, and then the other two are being used in String.format() to fill in that template.

Since exceptions generally serve as end-states of execution (avoid using exceptions as flow control, by the way), I really woldn't expect such classes to really do much of anything else beyond setting the exception message.

It's possible that a class that extends MyException could indirectly "use" the private variable by appending the error message that the constructor for MyException sets. Such classes would have access to getMessage(), so appending to the error message would be pretty straightforward.

// assuming MyException is declared as abstract or virtual...
public class MyChildException extends MyException{
    public MyChildException(){
        super(new MyType(), new OtherType(), new ThirdType());

        setMessage(getMessage() + '\n some extra information');
    }
}

In the end, deciding to structure classes like this is part of what I'd call the software arcitecture (or arcitectural decisions, or maybe software engineering). Pretty high-level stuff that tries to address issues like "how do I make sure that if I make a change in one class, other unrelated classes won't break?"

"Clean Code" by Robert C. Martin is a resource (general coding) I've heard recommended a few times if you'd like to get more into it.