2

Dear Salesforce StackExchange,

An outside partner set a precedent in some of our Apex triggers of doing major operations (such as DML) inside a try/catch block, and having the catch block simply contain a System.Assert(false, 'Blah blah blah failed'); statement inside it.

I like this because something feels right about not propagating deep stack traces up to a user in production code. Like teaching your kids to say you're busy, rather than not home, when they answer the phone to a stranger.

That said, if I get an error with production data and want to see what lies below the 'Blah blah blah failed' message, it's a royal pain to wait 20 minutes for validation tests to pass so I can replace the try-catch with a simple call to whatever was in the try block (to allow deeper errors to bubble up to me).

Does anyone have any efficient, secure, portable suggestions to improve this kind of code so I can simply "flip a switch" in the org and let the code know, "Someone's looking deeply at errors - let them bubble up"?

Specifically ... where in the Salesforce org would you recommend I put the "switch?"

  • Never use system.assert(false) in production code. – Adrian Larson Feb 16 '16 at 19:56
  • @AdrianLarson, thanks for the input, but can you elaborate why not? – k.. Feb 16 '16 at 19:58
  • 1
    the dan appleman advanced apex 3rd edition has a useful pattern for recording diagnostic data that may be useful to you – cropredy Feb 16 '16 at 20:06
  • 1
    I'm with @AdrianLarson here -- bubbling up the error is always helpful. It lets you diagnose quicker and, if the error happens a lot, indicates some missing validations or other problems with the code that should be fixed. If the code hits a limit exception or worse, a 'gack', sfdc doesn't hide that from the user, so, by inference, an error in your app's internal logic shouldn't be hidden either – cropredy Feb 16 '16 at 20:25
  • 1
    @AdrianLarson, thanks for editing my post - I hadn't noticed the "inline code" feature and will use it lovingly from now on! crop1645, too - you two have been very helpful; many thanks. – k.. Feb 16 '16 at 20:57
3

Take a look at An Introduction to Exception Handling.

For the record, I think there are better approaches to error handling than hiding the root cause. Personally, I would rather see Duplicate Value or Close Date must be in the future instead of Something went wrong.

If you want to maintain the existing pattern, you should use the SObject.addError method. Using system.assert(false) means that every dml operation is all or none, making it impossible to retain partially successful saves.

You can use a Hierarchy Custom Setting to toggle this behavior, with the advantage that you have granular control at the Profile or even User level. For example you can just make it so Hide DML is always false for System Administrators.

if (ExceptionHandling__c.getOrgDefaults().Hide_Dml__c)
{
    insert newRecords;
}
else
{
    insertAndHideExceptions(newRecords);
}

With the masking method looking something like:

try
{
    insert newRecords;
}
catch (DmlException dmx)
{
    for (Integer i = 0; i < dmx.getNumDml(); i++)
    {
        Integer index = dmx.getDmlIndex(i);
        newRecords[index].addError(SOME_GENERIC_MESSAGE);
    }
}

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.