0

After reading this article - Error Handling Best Practices for Lightning and Apex, I got a general picture of best practices regarding error handling for Lightning and Apex.

Yet I still didn't get it how to handle errors for Apex when a server-side action is triggered by the init event. Let me explain it with an example.

MyComponent.cmp

<aura:component controller="ApexController">
    <aura:attribute name="dataList1" type="String[]" default="[]"/>
    <aura:attribute name="dataList2" type="String[]" default="[]"/>

    <aura:handler name="init" value="{! this }" action="{! c.onInit }" />

    <lightning:select aura:id="select1" label="Select 1" >
        <aura:iteration items="{! v.dataList1 }" var="item">
            <option text="{! item }" value="{! item }" />
        </aura:iteration>
    </lightning:select>

    <lightning:select aura:id="select2" label="Select 2" >
        <aura:iteration items="{! v.dataList2 }" var="item">
            <option text="{! item }" value="{! item }" />
        </aura:iteration>
    </lightning:select>    
</aura:component>

MyComponentController.js

({
    onInit: function(component, event, helper) {
        helper.loadDataForSelect1(component);
        helper.loadDataForSelect2(component);
    },
});

MyComponentHelper.js

({
    loadDataForSelect1: function(component) {
        const action = component.get("c.getdData1");
        action.setCallback(this, function(response) {
            const state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.dataList1", response.getReturnValue());
            } else {
                let errors = response.getError();
                let message = 'Unknown error'; // Default error message
                // Retrieve the error message sent by the server
                if (errors && Array.isArray(errors) && errors.length > 0) {
                    message = errors[0].message;
                }
                // Display the message
                console.error(message);
            }
        });

        $A.enqueueAction(action);
    },
    loadDataForSelect2: function(component) {
        const action = component.get("c.getdData2");
        action.setCallback(this, function(response) {
            const state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.dataList2", response.getReturnValue());
            } else {
                let errors = response.getError();
                let message = 'Unknown error'; // Default error message
                // Retrieve the error message sent by the server
                if (errors && Array.isArray(errors) && errors.length > 0) {
                    message = errors[0].message;
                }
                // Display the message
                console.error(message);
            }
        });

        $A.enqueueAction(action);
    }
})

ApexController.cls

public with sharing class ApexController
{
    @AuraEnabled
    public static List<String> getdData1()
    {
        try {
            return new List<String> {'One', 'Two', 'Three'};
        }
        catch(Exception ex) {
            throw new AuraHandledException(ex.getMessage());
        }
    }

    @AuraEnabled
    public static List<String> getdData2()
    {
        try {
            return new List<String> {'Red', 'Green', 'Blue'};
        }
        catch(Exception ex) {
            throw new AuraHandledException(ex.getMessage());
        }
    }
}

Now assume that either getdData1() or getdData2() or both apex methods end up in error which is handled by the respective helper methods in the lightning component.

In the aforementioned blog article it is said:

Reporting the error in the console is a start, but the end goal is to display it to the user.

For me it's obvious that results of all user-initiated actions should be displayed to the user. For example, the user presses the button and if error occurs, we will display a toast with an error message.

But in case of data initialization process, should the user be notified at all when an error occurs? Or is console.error() enough here?

More generally speaking, how is it done in such cases?

3

As a best practice user should at-least be notified something like Your action cannot be completed. Please contact admin else nobody would report it until its too late.

Also, you didnt use error handling in Apex. You can have error handling in apex:

try {
    -- you code --
}
catch(Exception ex) {
    // also create a log object if you are using for tracking errors through error log object
    throw new AuraHandledException(ex.getMessage());
}

And in the component, as a general good practice, use lightning:notifications library to show some generic error message (to contact admin) as a toast message (along with logging actual error in console).

adding for comment
If there are multiple apex calls on init, then you should be using promises. loadDataForSelect1 and loadDataForSelect2 should return a promise. Then use below:

Promise.all([helper.loadDataForSelect1(component), helper.loadDataForSelect2(component)])
        .then(successResponse => console.log("success"))
        .catch(error => {
            // show toast of generic message
            console.error(error);
        });

Promise.all will wait for success of all functions passed, if any one of them fails, it goes to catch and shows error.

2
  • Thanks for your answer. I skipped error handling in apex for brevity, but added it now for completeness. My main goal here is to find out how exactly to handle errors occurred during data initialization. The toast message would work, but what to do if both getdData1() and getdData2() failed? Show 2 toasts simultaneously? – Eduard Jul 22 '19 at 11:33
  • editing the answer. – salesforce-sas Jul 22 '19 at 11:36
0

You can use a Response wrapper to send the data or an exception. Create a response wrapper which consists of status(Boolean), data(Serialized version of your data) and errormessage(String) properties. You can determine the status of the transaction using status of the response wrapper. If you get any error populate the status as false and populate the error message accordingly. In the controller, always check for status and then proceed accordingly.

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.