0

I love @wire(ing) LWC properties like

import { LightningElement, wire } from "lwc";

import getAccounts from "@salesforce/apex/MyCtrl.getAccounts";

export default class MyComponent extends LightningElement {

    @wire(getAccounts)
    accounts = [];
}

to a @AuraEnabled(cachable=true) Apex method

public with sharing class MyCtrl {

    @AuraEnabled(cacheable=true)
    public static List<Account> getAccounts() {
        try {
            return getViaCallout();
        }
        catch(Exception ex) {
            new ApplicationException().throwAuraHandled(ex);
        }

        return null;
    }
}

But I am unsure about how to handle errors gracefully. E.g. if an exception is thrown in Apex and rethrown as AuraHandledException. How do I catch and display it as an LWC standard toast?

If I would not use @wire I would do:

  loadAccounts() {
    getAccounts()
        .then((result) => {
            this.accounts = result;
        })
        .catch((error) => {
            this.toastError(error, "Appway: Unable to create process");
        });
}


toastError(error, title) {
    this.dispatchEvent(
        new ShowToastEvent({
            title: title,
            message: reduceErrors(error).join(", "),
            variant: "error"
        })
    );
}

2 Answers 2

1

When you wire a class field/property, you can handle error only in HTML. You cannot handle error in Javascript (to show toast) by using class property. JS:

@wire(getAccounts)
accounts = []; //class field/property

HTML:

<template if:true={accounts.error}                                              
    <c-error-panel errors={accounts.error}></c-error-panel>
</template>

If you need to use wire decorator and still use only Javascript for error handling, you need to pass wired data to function.

@wire(getAccounts)
wiredAccounts({ error, data }) {
    if (data) {
        this.accounts = data;
        this.error = undefined;
    } else if (error) {
        this.toastError(error, "Appway: Unable to create process");
        this.accounts = undefined;
    }
}

Additional Info:
You cannot use change handlers on properties (by using get/set methods) on tracked or wired properties. You can use them only on public properties (api decorated). Like below:

@api
get accounts() {
    return this._accounts;
}
set accounts(val) { //triggers whenever accounts change
    if (val.data) {
        this._accounts = val;
    } else {
        console.error(val.error);
    }
}
4
  • How does @wire function when an exception occurs? Does it display anything? Commented Jul 22, 2019 at 17:56
  • 1
    It is just the function which receives either data or error. It does not display anything by default. We need to handle the logic to display toast if data is undefined and error is not null. Did I understand your question correctly? Commented Jul 22, 2019 at 18:09
  • Is there a default component for errors?
    – Edmondo
    Commented Nov 7, 2020 at 10:40
  • @Edmondo1984 I do not think so. You need to handle using standard toast or display using HTML div with slds-theme_error class Commented Nov 8, 2020 at 4:19
3

With @wire, you can provide a method instead:

@track accounts = [];

@wire(loadAccounts) 
  wireAccountLoaded({data, error}) {
    if(data) {
      this.accounts = data;
    } else {
      this.toastError(error, 'Errors');
    }
  }

This is demonstrated in the documentation.

2
  • How does @wire function when an exception occurs? Does it display anything? Commented Jul 22, 2019 at 17:56
  • 1
    @RobertSösemann As stated in the other answer, nothing happens by default. It's up to you to do something. The example was in the documentation.
    – sfdcfox
    Commented Jul 22, 2019 at 18:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .