Handle Server Errors
Learning Objectives
After completing this unit, you’ll be able to:
- Explain how to handle server errors that occur when you wire a property.
- Explain how to handle server errors that occur when you wire a function.
- Explain how to handle server errors that occur when you call an LDS function or Apex imperatively.
- Identify the recommended way to interact with data and handle errors for a specific use case.
Handle Server Errors in Lightning Web Components
Errors thrown by LDS wire adapters, LDS functions, and calls to Apex have specific structures. To retrieve information about an error, you process the error response in your JavaScript code. Then you can show the content of the error to the user.
As the developer, you decide how to present errors to the user: an error panel, a toast message, or something else. For learning purposes, the examples in this module surface errors by referencing an errors property in the markup, like this:
errors.html
<template>
<template if:true={errors}>
<p>{errors}</p>
</template>
</template>
How you handle server errors in JavaScript depends on how you’re interacting Salesforce data. Let’s explore three examples: wired properties, wired functions, and imperative function calls.
Handling Errors on Wired Properties
When you use @wire to decorate a property, errors are accessible on the property error attribute. This is valid when you use @wire with an LDS wire adapter or with Apex.
wireApexProperty.js
import { LightningElement, api, wire } from 'lwc';
import { reduceErrors } from 'c/ldsUtils';
import getRelatedContacts from '@salesforce/apex/AccountController.getRelatedContacts';
export default class WireApexProperty extends LightningElement {
@api recordId;
@wire(getRelatedContacts, { accountId: '$recordId' })
contacts;
get errors() {
return (this.contacts.error) ?
reduceErrors(this.contacts.error) : [];
}
}
Code highlights:
- Line 2: We import the
reduceErrorshelper function from theldsUtilsmodule. (You add theldsUtilsmodule to your project later in this unit.) - Lines 6–7: We decorate the
contactsproperty with@wireto wire it to thegetRelatedContactsfunction. - Line 8: We define a getter function that creates a property named
errors. Every timethis.contacts.errorchanges, the getter updates the value of theerrorsproperty. This occurs because of reactivity. - Line 10: In the getter, we use the
reduceErrorshelper function to formatthis.contacts.error. The function reduces the received error objects and returns an array of all the error messages that have occurred.
Handling Errors on Wired Functions
When you use @wire to decorate a function, the function receives as a parameter an object that includes errors (if there are any errors). This applies when you use @wire with either LDS wire adapters or Apex.
wireApexFunction.js
import { LightningElement, api, wire } from 'lwc';
import { reduceErrors } from 'c/ldsUtils';
import getRelatedContacts from '@salesforce/apex/AccountController.getRelatedContacts';
export default class WireApexFunction extends LightningElement {
@api recordId;
errors;
@wire(getRelatedContacts, { accountId: '$recordId' })
wiredContacts({data, error}) {
if (error)
this.errors = reduceErrors(error);
}
}
Code highlights:
- Line 2: We import the
reduceErrorshelper function from theldsUtilsmodule (as we did in the wireApexProperty example). - Line 3: We import the
getRelatedContactsfunction from theAccountControllerclass. - Line 6: We define the
errorsproperty. - Lines 7–8: We decorate the
wiredContactsfunction with@wireto wire it to thegetRelatedContactsfunction. - Line 10: Each time the wired function receives an error, we use the
reduceErrorshelper function to format it. The function returns an array of all the errors that have occurred.
Handling Errors When Calling a Function Imperatively
If you call an LDS function or Apex method imperatively, the server returns errors as a parameter to the catch method’s callback function.
callApexImperative.js
import { LightningElement, api, wire } from 'lwc';
import { reduceErrors } from 'c/ldsUtils';
import getRelatedContacts from '@salesforce/apex/AccountController.getRelatedContacts';
export default class CallApexImperative extends LightningElement {
@api recordId;
errors;
handleButtonClick() {
getRelatedContacts({
accountId: this.recordId
})
.then(contacts => {
// code to execute if the promise is resolved
})
.catch(error => {
this.errors = reduceErrors(error); // code to execute if the promise is rejected
});
}
}
Code highlights:
- Line 2: We import the
reduceErrorshelper function. - Line 6: We define a property named
errors. - Line 8: We invoke the
getRelatedContactsfunction imperatively. The function returns a promise. - Line 11–13: If the promise is resolved, we process
contacts. - Line 14–16: If the promise is rejected, we use the
reduceErrorshelper function to format the received error and store it in theerrorsproperty.
Handle Errors in the accountList Component
Let’s add error handling to the accountList component that you created.
- In the accountList.html file, after the
<template>that includes thelightning-datatable, add this code:
<template if:true={errors}> <p>{errors}</p> </template> - Copy the
ldsUtilscomponent from LWC recipes and include it in the force-app/main/default/lwc folder in your project. This component contains thereduceErrorsfunction. - Import the
reduceErrorsfunction near the beginning of accountList.js.
import { reduceErrors } from 'c/ldsUtils'; - In accountList.js, insert this getter, which defines an
errorsproperty:
get errors() { return (this.accounts.error) ? reduceErrors(this.accounts.error) : []; } - To test the error handling, force the
getAccountsmethod (in AccountController.cls) to throw an error by commenting the body of the method (temporarily), and adding this code in its place:
throw new AuraHandledException('Forced error'); - Save the three files that you edited: accountList.html, accountList.js, and AccountController.cls.
- Deploy the project files (from
force-app/main/default). - If it’s not already open, open your Trailhead Playground.
- To check the result, refresh the Working with Data page.
Hint: Because Lightning Data Service caches results, you may need to clear the cache before you can see your forced error in action.
Summary
Now you know several ways to interact with Salesforce data in your Lightning web components. Some solutions are preferred to others under certain circumstances. This table summarizes recommended solutions by use case.
Use Cases for Interacting with Salesforce Data
| Use Case |
Recommended Solution |
Notes |
|---|---|---|
| View or edit a record specifying its layout or a list of fields |
lightning-record-form
|
|
| View a record with a custom form layout or custom rendering of record data |
lightning-record-view-form
|
|
| Edit a record with a custom form layout, custom rendering of record data, or prepopulated field values |
lightning-record-edit-form
|
|
| Read metadata or read data for one record |
LDS wire adapters |
Can be combined, but operations will run on independent transactions |
| Create, edit, or delete one record |
LDS functions |
Can be combined, but operations will run on independent transactions |
| Read multiple records |
Call Apex with @wire
|
Annotate the Apex method with cacheable=true
|
| Read multiple records on a one-time invocation or modify multiple records |
Call Apex imperatively |
For reads, annotate the Apex method with cacheable=true
|
When you work with data in Lightning web components, error handling varies. How you access errors depends on how you’re interacting with the data.
Handling Server Errors
| How to Work with Data |
How to Access Server Errors |
|---|---|
| Use either an LDS wire adapter or an Apex method, and decorate a property |
Use reduceErrors to handle the error that’s returned to the wired property in decoratedProperty.error
|
| Use either an LDS wire adapter or an Apex method, and decorate a function |
Use reduceErrors to handle the error that’s returned in the object parameter received by the wired function decoratedFunction({data, error}) {...}
|
| Imperatively invoke either an LDS wire function or an Apex method |
Use reduceErrors to handle the error that’s received as a parameter on the catch method's callback function functionToInvoke()
|
Wrap Up
In this module, you learned about different ways to work with Salesforce data in Lightning web components. You learned the pros and cons of each technique, when each is recommended, and how to implement each solution. You also learned how to handle server errors in Lightning web components, based on how you interact with Salesforce data.
To keep learning about working with Salesforce data in Lightning web components, check out the resources provided in this module. Also, see Quick Start: Explore the Recipes Sample App for more examples and the code to implement them.