Error Handling in Visualforce with <apex:pageMessages>

A big part of building Visualforce pages is making sure that the human has a good experience while interacting with the page(s) you've designed. This means that you need to have a good way of handling errors when and if they occur.

In this post I will highlight one of the simplest ways to handle an error by utilizing the apex:pageMessages tag within your Visualforce page. Let's imagine that the business requirements for this example are such that Users in the organization need to be able to edit a Contact and then be redirected to Home tab. As an admin you should already be aware that standard Salesforce functionality dictates that when you create or edit a Contact record you end up back on the record detail page after the Save button is clicked.

To keep things simple we will start with a Visualforce page that allows us to edit just a few fields for a Contact record. When you create this page (Setup > Develop > Pages then click the New button) please name it editContactRedirect.

<apex:page extensions="editContactRedirect" standardController="Contact">
<!--
	Created by: Greg Hacic
	Last Update: 27 August 2015 by Greg Hacic
	Questions?: greg@interactiveties.com
-->
	<apex:sectionHeader title="Contact Edit" subtitle="{!Contact.Name}" help="http://interactiveties.com/blog"></apex:sectionHeader>
	<p>Contacts not associated with accounts are private and cannot be viewed by other users or included in reports.</p>
	<apex:pageMessages></apex:pageMessages>
	<apex:form>
		<apex:pageBlock title="Contact Edit" id="pageBlock" mode="edit">
			<apex:pageBlockButtons>
				<apex:commandButton action="{!save}" value="Save"></apex:commandButton>
				<apex:commandButton action="{!cancel}" value="Cancel"></apex:commandButton>
			</apex:pageBlockButtons>
			<apex:pageBlockSection columns="2" title="Contact Information">
				<apex:pageBlockSectionItem> <!--allows us to group multiple child elements into one column in one row -->
					<apex:outputlabel value="First Name"/>
					<apex:outputpanel>
						<apex:inputField value="{!Contact.Salutation}"></apex:inputField>
						<apex:inputField style="width: 100px;" value="{!Contact.FirstName}"></apex:inputField>
					</apex:outputpanel>
				</apex:pageBlockSectionItem>
				<apex:inputField value="{!Contact.Phone}"></apex:inputField>
				<apex:inputField value="{!Contact.LastName}" required="true"></apex:inputField>
				<apex:inputField value="{!Contact.MobilePhone}"></apex:inputField>
				<apex:inputField value="{!Contact.AccountId}"></apex:inputField>
				<apex:inputField value="{!Contact.Email}"></apex:inputField>
				<apex:inputField value="{!Contact.Title}"></apex:inputField>
				<apex:inputField value="{!Contact.Fax}"></apex:inputField>
				<apex:inputField value="{!Contact.Department}"></apex:inputField>
				<apex:inputField value="{!Contact.Birthdate}"></apex:inputField>
			</apex:pageBlockSection>
		</apex:pageBlock>
	</apex:form>
</apex:page>

As you can see within the code above we will use the standard controller for the Contact object and use an extension for the page in order to handle the redirect after save. That Apex extension class is below:

/*
	Created by: Greg Hacic
	Last Update: 27 August 2015 by Greg Hacic
	Questions?: greg@interactiveties.com
	
	Notes:
		- used by editContactRedirect.page
*/
public class editContactRedirect {
	
	private final Contact c; //Contact object
	
	//constructor
	public editContactRedirect(ApexPages.StandardController stdController) {
		this.c = (Contact)stdController.getRecord(); //instantiate the standard controller
	}
	
	//method for handling when the Cancel button within the Visualforce page is clicked
	public PageReference cancel() {
		PageReference pageWhereWeEndUp = new ApexPages.StandardController(c).view(); //create a PageReference object for the current Contact detail page
		pageWhereWeEndUp.setRedirect(true); //set the object to use a client side redirect
		return pageWhereWeEndUp; //send the User on their way
	}
	
	//method for handling when the Save button within the Visualforce page is clicked
	public PageReference save() {
		try { //attempt
			update c; //update the record using the values from the Visualforce page
			PageReference pageWhereWeEndUp = new PageReference('/home/home.jsp'); //create a PageReference object for the Home tab
			return pageWhereWeEndUp.setRedirect(true); //set the object to use a client side redirect and send them on their way
		} catch(DMLException e) { //must have been an issue with the update
			ApexPages.addMessages(e); //display the error message to the User
			return null; //return null so DMLException can be displayed to the User
		}
	}

}

Within the try catch statement we basically attempt to save the updated record and if that DML operation fails for any reason then we will grab the DML error response and use the addMessages method to kick that information back to the Visualforce page so the human can make sense of what is happening.

The apex:pageMessages tag within the Visualforce page then interprets the error response provided by the class and formats/displays the error.

Copy and paste the Visualforce page and Apex class into your developer org and access the page for an existing contact record in your org. You can access the page using a URL similar to the following:

https://na2.salesforce.com/apex/editContactRedirect?id=003j0000001Wlq1

Where "na2" is replaced by the instance for your particular Salesforce org and "003j0000001Wlq1" is replaced by the Id for a Contact specific to your org also.

To see how this logic works you should create some bad data like removing the last name, using an email with no @ symbol and writing text in the Birthdate field and click the Save button.

Handling errors in this way prevents the developer from having to worry about the CSS or other formatting issues that may otherwise be necessary for displaying any error messaging to the human.

Automated Exchange Rates in Salesforce.com

Reduce Repetitive Tasks, Eliminate Errors & Free Up Your Administrators.

Birthday Reminders for Salesforce.com

It might lead to a sale. Or it might make you feel good.