1

I'm working on writing tests for someone else's code and they have an try/catch around a SELECT statement. Is it possible to ever get an exception in something like the below code block as long as it is being returned to a list? I'm trying to find out if I need to cover the exception block or if I can just remove it.

I know it can happen if you are returning the results to a single object and it doesn't have any results to return, but I don't think it is possible if you return to a list. I'm trying to find if there is an official answer that I can point to if I'm questioned on why I'm removing the try/catch.

public static void processOpportunity(Id opportunityId) {
        List<Opportunity> opportunities;
        try {
            opportunities = [SELECT Id, Name FROM Opportunity WHERE Id = :opportunityId];
        }
        catch (Exception ex) {
            System.debug('Exception: ' + ex.getMessage());
            // log exception
        }

        // do stuff with opportunity
    }

2

No, that construct cannot throw any catchable exception. It can throw LimitException, but that's irrelevant because you cannot catch it.

More generally, handlers that catch the generic Exception and "handle" it via System.debug() are a terrible pattern that produces unexpected, integrity-breaking behavior in code and makes debugging a nightmare. There are few to no situations where this construct should be used.

The answer to the more general question in your title, though (as it sounds like you're already aware) is yes. There are multiple reasons a SOQL statement other than this one can cause an exception to be thrown, including assigning a query result returning something other than a single result to an sObject variable, using the FOR UPDATE clause and failing to get a lock, and using the WITH SECURITY_ENFORCED clause.

| improve this answer | |
  • Thanks that helps. Also, the catch does more, but I had to strip out all the other details per company policy. – aaron Feb 25 at 17:38
  • @aaron This question has some interesting further reading on the subject, with another excellent answer by David Reed: salesforce.stackexchange.com/questions/295708/… – Kasper Feb 25 at 18:00
1

You could get a QueryException either by row locks (i.e. another process has queried the record and is still running), or by passing in an invalid Id. For example:

YourClass.processOpportunity('006000000000000AAA');

This will fail to query the record, since that's not actually a record you can query.

In practice, though, it doesn't usually make sense to use try-catch blocks unless you're also using a FOR UPDATE clause to lock the record (which I would advise anyways, if you intend to update a record).

| improve this answer | |
0

Technically a query can throw a catchable exception. If it attempts and fails to row lock, you will get a QueryException.

try
{
    opportunities = [SELECT ... FROM Opportunity WHERE ... FOR UPDATE];
}
catch (QueryException e)
{
    // failed to lock row
}
| improve this answer | |
  • I wasn't aware of that scenario. Is it possible to create a scenario in a unit test case to cover that type of exception? – aaron Feb 25 at 18:13
  • You would likely need to use mocking to generate the exception. – Adrian Larson Feb 25 at 18:14
  • If I understand correctly, they query in the try/catch block would also need a 'FOR UPDATE' clause to potentially trigger an exception. As long as that query inside the block doesn't need locking, it still won't be possible to trigger a catchable exception? Is that correct? – aaron Feb 25 at 18:27
  • 1
    Correct, if the query does not attempt a lock, it can't throw an exception you could catch. I just thought it was worth pointing out because the accepted answer might indicate to some there are no circumstances under which it could generate an error, but that is not the case. – Adrian Larson Feb 25 at 18:29
  • 1
    @AdrianLarson As another exception (pun intended), an Id for a deleted or non-existent record could be passed in, also causing an exception. – sfdcfox Feb 25 at 18:33

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.