Start tracking your progress
Trailhead Home
Trailhead Home

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 reduceErrors helper function from the ldsUtils module. (You add the ldsUtils module to your project later in this unit.)
  • Lines 6–7: We decorate the contacts property with @wire to wire it to the getRelatedContacts function.
  • Line 8: We define a getter function that creates a property named errors. Every time this.contacts.error changes, the getter updates the value of the errors property. This occurs because of reactivity.
  • Line 10: In the getter, we use the reduceErrors helper function to format this.contacts.error. The function reduces the received error objects and returns an array of all the error messages that have occurred.
Note

Note

The reduceErrors helper function in this example comes from the ldsUtils module of the LWC Recipes sample app. LWC Recipes contains easy-to-digest examples of common patterns implemented as Lightning web components. Feel free to copy the ldsUtils module into your project, and use the reduceErrors function.

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 reduceErrors helper function from the ldsUtils module (as we did in the wireApexProperty example).
  • Line 3: We import the getRelatedContacts function from the AccountController class.
  • Line 6: We define the errors property.
  • Lines 7–8: We decorate the wiredContacts function with @wire to wire it to the getRelatedContacts function.
  • Line 10: Each time the wired function receives an error, we use the reduceErrors helper 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: '$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 reduceErrors helper function.
  • Line 6: We define a property named errors.
  • Line 8: We invoke the getRelatedContacts function 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 reduceErrors helper function to format the received error and store it in the errors property.

Handle Errors in the accountList Component

Let’s add error handling to the accountList component that you created.

  1. In the accountList.html file, after the <template> that includes the lightning-datatable, add this code:
    <template if:true={errors}>
        <p>{errors}</p>
    </template>
  2. Copy the ldsUtils component from LWC recipes and include it in the force-app/main/default/lwc folder in your project. This component contains the reduceErrors function.
  3. Import the reduceErrors function near the beginning of accountList.js.
    import { reduceErrors } from 'c/ldsUtils';
  4. In accountList.js, insert this getter, which defines an errors property:
    get errors() {
        return (this.accounts.error) ?
            reduceErrors(this.accounts.error) : [];
    }
  5. To test the error handling, force the getAccounts method (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');
  6. Save the three files that you edited: accountList.html, accountList.js, and AccountController.cls.
  7. Deploy the project files (from force-app/main/default).
  8. If it’s not already open, open your Trailhead Playground.
  9. 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()
.then(data => {...})
.catch(error => {...});

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.

Resources