On the backend, the component javascript detects the type of error object it receives. Depending on which process fails,
the error object will look slightly different. We are involving some logic here to ensure we drill down to the error message
and details that are relevant.
//lwcErrorHandling.html
<template>
<!--banner-->
<div class="slds-notify slds-notify_alert slds-theme_alert-texture slds-theme_error" role="alert">
<!--error graphic-->
<span class="slds-icon_container slds-icon-utility-error slds-m-right_x-small" title="Description of icon when needed">
<lightning-icon icon-name="utility:error" alternative-text="Error" title="Error" variant="inverse"></lightning-icon>
</span>
<!--error message-->
<h2>{errorMessageToDisplay}</h2>
<!--close button-->
<div class="slds-notify__close">
<button class="slds-button slds-button_icon slds-button_icon-small slds-button_icon-inverse" title="Close" onclick={closeError}>
<lightning-icon icon-name="utility:close" alternative-text="Close" title="Close" variant="inverse"></lightning-icon>
</button>
</div>
</div>
</template>
//lwcErrorHandling.js
import { LightningElement, api, track } from 'lwc';
export default class LwcErrorHandling extends LightningElement {
@api error;
errorMessageToDisplay = '';
// this runs every time this component is loaded
connectedCallback(){
this.errorMessageToDisplay = 'An error occurred \n';
console.log(this.error);
// getting meaningful error message depending on error type
// handles errors from wire & regular apex methods
if(this.error.body){
if (Array.isArray(this.error.body)) {
this.errorMessageToDisplay += this.error.body.map(e => e.message).join(', ');
}
else if(typeof this.error.body === 'object'){
let fieldErrors = this.error.body.fieldErrors;
let pageErrors = this.error.body.pageErrors;
let duplicateResults = this.error.body.duplicateResults;
let exceptionError = this.error.body.message;
if(exceptionError && typeof exceptionError === 'string') {
this.errorMessageToDisplay += exceptionError;
}
if(fieldErrors){
for(var fieldName in fieldErrors){
let errorList = fieldErrors[fieldName];
for(var i=0; i < errorList.length; i++){
this.errorMessageToDisplay += errorList[i].statusCode + ' ' + fieldName + ' ' + errorList[i].message + ' ';
}
}
}
if(pageErrors && pageErrors.length > 0){
for(let i=0; i < pageErrors.length; i++){
this.errorMessageToDisplay += pageErrors[i].statusCode + ' '+ pageErrors[i].message;
}
}
if(duplicateResults && duplicateResults.length > 0){
this.errorMessageToDisplay += 'duplicate result error';
}
}
}
// handles errors from the lightning record edit form
if(this.error.message){
this.errorMessageToDisplay += this.error.message;
}
if(this.error.detail){
this.errorMessageToDisplay += this.error.detail;
}
}
// runs when the close button on the error banner is clicked
closeError() {
// reset variables
this.errorMessageToDisplay = '';
this.error = null;
// create a custom event for resetting the error state
const closeErrorEvent = new CustomEvent("errorclosed", {
detail: this.error
});
// dispatch the custom event to the parent component, this resets the error and hides this component
// if the parent component triggers another error, this entire component loads again and runs through the connectedCallback logic
this.dispatchEvent(closeErrorEvent);
}
}
//accountinfo.html :
<template>
<!-- error handling -->
<template if:true={error}>
<c-errorhandling error={error} onerrorclosed={handleError}></c-errorhandling>
</template>
<lightning-card title="Account Info" icon-name="standard:account">
<div class="slds-p-around_small">
<!-- record edit form-->
<lightning-record-edit-form record-id={recordId} object-api-name="Account" onerror={handleFormError}>
<lightning-input-field field-name='Name'></lightning-input-field>
<!-- submit button -->
<lightning-button class="slds-m-top_small button-fixed" variant="brand" type="submit" name="save" label="Save"></lightning-button>
</lightning-record-edit-form>
<!-- child component -->
<c-accountinfochild></c-accountinfochild>
</div>
</lightning-card>
</template>
// accountinfo.js
import { LightningElement, api } from 'lwc';
export default class Accountinfo extends LightningElement {
@api recordId;
error;
// handle error from child components
errorCallback(error, stack){
this.error = error;
}
// handle errors from self (submit button press)
handleFormError(event){
this.error = event.detail;
}
// handle errors from self
handleError(error){
this.error = error;
}
}
//accountinfochild.html
<template>
<lightning-button variant="brand" label="Click me" title="Click me" onclick={doSomething} class="slds-m-left_x-small"></lightning-button>
</template>
// accountinfochild.js
import { LightningElement } from 'lwc';
export default class Accountinfochild extends LightningElement {
doSomething() {
throw new Error('Whoops!');
}
}
No comments:
Post a Comment