Exception Class Methods

Issue #2353 wontfix
Oleksandr Tymchenko created an issue

Hello,
I’ve found that IC2 doesn’t have this method build in, however they exists and deployment is successful.
DMLException and EmailException Methods are missing.
https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_classes_exception_methods.htm

Comments (7)

  1. Scott Wells repo owner

    Hi. IC2 does have that method, but you must cast the exception to DmlException to reference it, e.g.:

    // Generated by Illuminated Cloud on Wed Apr 26 14:03:38 CDT 2023. Do not edit.
    
    global class /*System.*/DmlException extends Exception 
    {
        ...
    
        global List<String> getDmlFieldNames(Integer index)
        {
        }
    
        global List<SObjectField> getDmlFields(Integer index)
        {
        }
    
        global String getDmlId(Integer index)
        {
        }
    
        global Integer getDmlIndex(Integer index)
        {
        }
    
        global String getDmlMessage(Integer index)
        {
        }
    

    I say “must” because IC2 is treating the reference as the declared type, though if that code does compile in Salesforce, it must be doing some kind of polymorphic behavior based on the enclosing instanceof check or something. That’s certainly unexpected, and I’ll check with Salesforce whether that’s in fact the case, but that code can be made valid, both in IC2 and from a traditional OO/RTTI standpoint, by casting e to DmlException before accessing those methods.

  2. Scott Wells repo owner

    I’ve verified that the Apex compiler/runtime seems to evaluate any instance of Exception as the union set of all methods available on all (system) exceptions. So for example, the following:

    try
    {
        throw new IllegalArgumentException('Hi.');
    }
    catch (Exception e)
    {
        System.debug(e.getNumDml());
    }
    

    compiles just fine but results in the following at runtime:

    08:14:57.129 (144254616)|EXCEPTION_THROWN|[17]|IllegalArgumentException: Hi.
    08:14:57.129 (144790367)|FATAL_ERROR|System.TypeException: Procedure is only valid for System.DmlException and System.MailException
    
    (System Code)
    AnonymousBlock: line 21, column 1
    

    That leaves a certain class of avoidable errors to be found at runtime, whereas IC2 is showing you that you need to access that exception as the type that defines (or in this case, at least supports) those methods. IMO IC2’s type-safe approach is preferable to the actual system behavior.

  3. Scott Wells repo owner

    Resolving this one as "won't fix" (which I almost never do) because one of the key goals in IC2 is to find as many of the potential issues in a code base as possible before deployment and certainly before runtime. Given that supporting this behavior allows a detectable class of issues to be deferred until runtime--and given that the reported issue is easily resolved by casting to the correct type (after an instanceof check to ensure it is that type)--I think the current behavior is correct.

  4. Oleksandr Tymchenko reporter

    Thank you Scott for that,
    Then I think this method also should not be visible for the general Exception because it’s for the “QueryException” only, yes?

  5. Scott Wells repo owner

    Yes, that’s correct, but that’s being added by the Salesforce Tooling API’s completions resource…which is obviously inconsistent given that they don’t do the same for the DmlException/EmailException-specific methods. However, while I augment and modify(/correct) things that come from that API, I don’t typically remove things. I might make an exception (pun intended) for that one, though. Still mulling on that…

  6. Scott Wells repo owner

    Interestingly, the completions resource adds getInaccessibleFields() to all system Exception types:

    so to make that right, IC2 would need to remove that method from everything but QueryException. I think I’ll just raise that as a bug with Salesforce and see what they think.

  7. Log in to comment