1

I need to throw exceptions within my apex classes here and there, as most of us do. In fact, we can't throw built-in exceptions so we have to create a custom one that extends from the main exception class. I face a situation most often where there is a built-in exception that completely matches my situation, let's say the InvalidParameterValueException when an empty string is passed as a param to a method. I have created a custom exception with the exact same name and am able to use it with no problem. My question is: Is there a problem to do this? and I know that I can just simply change the exception name slightly to differentiate the built-in one from my custom one, but this question is just for clarification on what are potential issues that can occur and the risk involved. Thanks!

2 Answers 2

8

You can, except that if you do so, if any other code anywhere in your code base references that exception, you may get unexpected results. For example, consider:

public class DmlException extends Exception {
    /* Implementation here */
}

And somewhere else in your code base:

try {
    insert records;
} catch(DmlException e) {
    /* handle the error */
}

You'll be surprised to find that this exception will not be caught. You've just shadowed the default exception with a custom one, and now none of those try-catch blocks will work.

Every time you use that try-catch, you'll get:

Uncaught System.DmlException: ... blah blah blah ...

You'd have to scour your entire code base, and replace all of them:

try {
    insert records;
} catch(System.DmlException e) {
    /* handle the error */
}

Also, you'll be inviting anyone else who ever works on your code, ever, to fall in to the same trap (including your future self a year from now that forgot that you did this).

So, while you technically can, I strongly advise that you do not, as it can, and probably will, break completely unrelated code in hilarious but infuriatingly difficult-to-fix and/or difficult-to-debug ways.

Finally, there are other subtle nuances, such as the fact that you may break unmanaged or unlocked packages that do not expect you do override a default exception class (managed packages would be safe from this problem, however).

1

sfdcfox is quite correct in his answer that you can but shouldn't create your own exception with the same name.

It's worth pointing out that in the example you gave, InvalidParameterValueException, you can can construct and throw the system exception e.g.

@IsTest
private class ThrowSystemExceptionTest {

    public class ThrowSystemEx {
        public ThrowSystemEx() {
            InvalidParameterValueException e = new InvalidParameterValueException('a', 'b');
            e.setMessage('Expected better parameters');
            throw e;
        }
    }

    @IsTest
    static void uncaught() {
        new ThrowSystemEx();
    }
    @IsTest
    static void caught() {
        try {
            new ThrowSystemEx();
        } catch(InvalidParameterValueException e) {
            System.debug('Caught with message: ' + e.getMessage());
        }
    }
}

The uncaught() example fails the test, but with the sort of stack trace you'd hope for with a normal exception.

The caught() example shows that you can catch and handle the exception as normal.

Throwing the system exception probably solves your underlying problem with the minimum of ugliness.

1
  • Thanks for your answer! would you please explain on how comes it’s possible to construct the InvalidParameterValueException in the class constructor?
    – Bahman.A
    Commented Mar 26, 2020 at 14:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .