aka Essential Eight Lessons for Error Handling in Lightning Custom Component Development.
Covering some of the common pitfalls of handling errors when developing Lightning Components and my own modest recommendations for how you can avoid them, plus some best practices. As part of my role at Provar I get asked to investigate when our customer's tests are seen to be failing in order to diagnose whether the fault is in Salesforce or a missing feature of Provar. I've learned the astonishing ways in which people are publishing code for Lightning Components without basic error handling to a point I'd argue is irresponsible! This led me down a deeper and deeper rabbit hole which, like Alice, I'd like to share so you can all safely reach the Lightning Wonderland!
2. Head of Salesforce Engineering, Provar
• Developing Salesforce.com relationship
• Defining Salesforce integration roadmap
• Accelerate new development
• Increase functional coverage
• SFDC SME
Background
• 10y Salesforce.com
• 3x DF speaker
• 5 AppExchange & 3 ISV Apps
• Co-organiser London SF Developer’s Meetup
• Former CTO makepositive & Brightgen
• 2x former Provar customer!
Richard Clark
Twitter/LinkedIn: @RichClark808
http://provartesting.com
About Me
3. About Provar
Point and click test
creation
Runs UI and API
steps in the same test
Highly maintainable test
cases
Aligned to the
Salesforce roadmap
Provar is the only automated testing tool for Salesforce.
@Provar
http://ProvarTesting.com
4. References… (eh, already?)
Independent Blogs/Forums
1. How to Handle Apex Errors for
Lightning
2. Exception Handling in Lightning
3. Testing AuraHandledExceptions
4. Lightning Error Handler
5. Best practice catching errors in
Lightning
Official Salesforce
1. Throwing & Handling Errors
2. Set an Error Response
3. ui:inputDefaultError
4. Validating Fields
5. Returning Errors from Apex
6. Validating Fields
7. lightning:notificationsLibrary
8. Lightning Messaging Framework
8. Lesson 2 - Validation is 2 Step!
● Depending on the component library you use:
○ For <ui:inputXXXXX /> use
inputCmp.set("v.errors", [{message:"your msg"}]);
See Validating Fields
○ For <lightning:input/select/textarea > use
inputCmp.showHelpMessageIfInvalid();
9. Helper:
validateForm: function(component) {
var valid = true;
// Show error messages if field validation fails
var uiValid = component.find('contactField').reduce(
function (validFlds, inCmp) {
inCmp.showHelpMessageIfInvalid();
return validFlds &&
inCmp.get('v.validity').valid;
},
true);
if (uiValid) {
// Do any client side validation e.g. Account isActive
}
return(valid);
}
lightning:input
In your Component Controller:
handleSave: function(comp, evt, hlpr)
{
if (hlpr.validateForm(comp)) {
//do stuff
}
10. ● Public examples rarely handle server errors
○ console.log() and //Do something is not enough!
● Demo: Validation Rule on Contact
● Demo: DML, Server and Dupe Warnings
● Demo: Handling the Validation Rule properly
Lesson 3 - Silent but Deadly...
11. ● Use console.error(); instead of console.log(); unless it’s a warning
● Display something (next lesson)
● response.getState(), has 4 states - deal with them all
a. SUCCESS
b. DRAFT (if using LDS and Local Cache)
c. ERROR
d. INCOMPLETE (offline/session expired)
What does ‘properly’ mean
15. showToast vs notificationsLibrary
var resultsToast = $A.get("e.force:showToast");
resultsToast.setParams({
"title": "Contact Saved",
"message": "The new contact was created."
});
resultsToast.fire();
<!-- Component markup -->
<lightning:notificationsLibrary aura:id="notifLib"/>
// JS Controller
component.find('notifLib').showToast({
"variant" : “success”,
"title": "Contact Saved",
"message": "The new contact was created"
});
16. Spring 18: lightning:messages
● Spring18 (API 42.0)
○ <lightning:messages/>
○ No, it wasn’t in the release notes! See here
○ And it doesn’t appear in ./componentReference/suite.app
○ But it is in other examples in the Lightning Components Dev Guide
Demo (from Spring 18: Interactive Forms article)
○ It avoids silent failures and is ‘plumbing free’
○ Doesn’t (yet) support duplicate warnings
○ Doesn’t provide any message details (s.t. docs)
○ Keep an eye on it for the future, great catch-all for now
17. ● If creating components for LightningOut/Visualforce…
○ UI Validation does work
○ showToast not supported in VF (Classic or LEX)
○ So use ui:outputtext/ui:message
● Make your error handling Environmentally Friendly!
○ What & Why: Lightning Messaging Overview
○ How:
http://bobbuzzard.blogspot.co.uk/2015/11/context-is-everything.html
Lesson 5 - LightningOut
18. ● UI Validation
● Duplicate Rules
● Data Model Validation Rules
● Apex DMLExceptions
● Other Apex Exceptions (e.g. NullPointer, Custom)
● Salesforce Platform Errors/Limits
Recap - Errors to handle
19. Three areas to check within your JS error handler:
● pageErrors: e.g. Apex Exceptions, Dupe Rules, Validation
● fieldErrors: e.g. Field validation
● potentialDuplicates:* TBC!
Expect multiple errors and display them all (as appropriate).
Lesson 6 - Server Errors
20. Three areas to check within your JS error handler:
● pageErrors: e.g. Apex Exceptions, Dupe Rules, Validation
● fieldErrors: e.g. Field validation
● potentialDuplicates:* TBC!
Expect multiple errors and display them all (as appropriate).
Lesson 6 - Server Errors
21. // What does the user see?
Account a = new Account();
insert a; // Whoops, I broke Salesforce?
Lesson 7 - AuraHandledException
Apex Custom Controller method using @AuraEnabled
22. // What does the user see?
try {
Account a = new Account();
insert a;
}
catch (Exception ex) {
AuraHandledException ahe = new
AuraHandledException(“Unexpected Error:
”+ex.getMessage());
ahe.setMessage(“Err in accCreate:”+ex.getStackTrace());
throw ahe;
}
Lesson 7 - AuraHandledException
Apex Custom Controller method using @AuraEnabled
24. Lesson 7 (cont’d)
Lightning Components Developer Guide:
“The benefit of throwing AuraHandledException, instead of letting a system exception be
returned, is that you have a chance to handle the exception more gracefully in your client code”
Some quirks to be aware of:
● catch (DMLException) & throw AuraHandledException:
○ message is less readable than throwing DMLException
○ or parse out the ugly message
● catch (Exception) & throw AuraHandledException
○ Avoids “Internal Server Error”
● AuraHandledException.setMessage() for meaningful messages in debug
logs instead of “Script thrown exception”
25. ● Develop your own re-usable custom error component
○ Consistency across your application
○ Single point of change
○ Easy to implement
● Don’t forget i18n for your messages:
○ $A.get(“$Label.c.labelName”);
○ $A.get(“$Label.namespace.labelName”);
● Here’s a useful starting point: Lightning Error Handler plus
<lightning:notificationsLibrary/>
Final Lesson - Error Component