Handling Exceptions with Salesforce and Slack

Roger Mitchell
4 min readJun 11, 2015

--

Exception handling is a great practice for any developer, though Salesforce developers only get exceptions if they are monitoring a debug log, or were the last user to deploy components to production. This paradigm is fine for smaller orgs, but it cannot scale to support ISVs or teams that support multiple orgs.

I decided to create ExceptionForce after mulling over how to collect exceptions that occur on platform, and had inspiration from a Salesforce Developers blog post back in October 2014. The architecture is fairly simple, whenever you leverage try…catch, you call a method in a utility class that will “handle” the exception. Handling an exception has a few flavors depending upon how you’d like to receive notifications about exceptions.

try {
insert accountList;
} catch(Exception e) {
ExceptionUtils.handleException(e, true, true);
}

Passing the exception caught along with two boolean parameters controls how the method will proceed. Our first boolean sets whether to create a record in the Exception custom object, and our second boolean sets whether to send a post to the Slack Web API (specifically the chat.postMessage method).

Both flavors allow you to capture the following details about the exception, and with the Exception custom object, you can leverage declarative options to send email alerts or post to a Chatter feed.

  • Cause
  • Line Number
  • Message
  • Stack Trace String
  • Type Name

Why use ExceptionForce?

Capturing exceptions based on your existing codebase is as simple as adding a line to every catch{}, and this will allow your team to centralize issues and manage them accordingly. I decided to keep this open source and as an unmanaged package (for an easier installation) to allow teams to extend it further, or embed it further into their workflows.

How do I install and set up ExceptionForce?

You can either clone this Github repo and deploy the components into your org, or use the installation links for your production or sandbox orgs. If you are interested in Slack integration, skip a section below that details specifically how to set up a Slack integration with ExceptionForce.

Here’s a code snippet that you can execute in your Developer Console’s Execute Anonymous window. This particular case will fail because we are attempting to create an Account without specifying a value for the Name field.

// Generate an exception, catch, and log with ExceptionForce
Account fail = new Account();
try{
insert fail;
} catch(Exception e) {
ExceptionUtils.handleException(e, true, false);

System.debug(‘### getCause ‘ + e.getCause());
System.debug(‘### getLineNumber ‘ + e.getLineNumber());
System.debug(‘### getMessage ‘ + e.getMessage());
System.debug(‘### getStackTraceString ‘ + e.getStackTraceString());
System.debug(‘### getTypeName ‘ + e.getTypeName());
}

We have set our handleException() method to create a record in the Exception object and not post the details to a Slack channel. Below is an example of what this exception record looks like within ExceptionForce.

Exception caught and created as part of our anonymous block above.

How do I set up Slack with ExceptionForce?

If you’re interested in Slack, it’s assumed that you already have an account; if not, go check it out at Slack.com. You’ll need to create an authentication token, which can be done from this site. Copy and paste the string that’s blocked out by the big orange bar below; you’ll use this when creating a Custom Setting a few steps later.

Next, we’ll want to retrieve the channel ID that will be used for our integration. You may want to create a new channel first if you don’t have a centralized #errors channel, or wish to keep Salesforce exceptions to its own channel. Retrieving a channel ID can be accomplished by using the channel.list method directly from the browser. Check the JSON returned for the name of your channel, and grab the ID (below this is C12345678).

{
"ok": true,
"channels": [
{
"id": "C12345678",
"name": "errors",
"is_channel": true,
"created": 10101010,
"creator": "U0000000",
"is_archived": false,
"is_general": false,
"is_member": true,
"members": [
"U0000000"
],

Our final step is to create a record of the Slack Service custom setting. We’ll use the token and channel ID, along with a few other attributes to personalize our bot with a name and icon.

  • Name: doesn’t really matter… call it “Slack Errors”
  • Token: copy/paste the token from our first step
  • Channel ID: copy/paste the channel ID from our second step
  • Username: the name of the “bot” that posts into the channel
  • Icon URL: the avatar of the “bot”
  • API URL: https://slack.com/api/chat.postMessage

After you finish this, you can go back to the Developer Console and execute the script we used above, but set the third parameter of handleException() to true.

// Generate an exception, catch, and log with ExceptionForce
Account fail = new Account();
try{
insert fail;
} catch(Exception e) {
ExceptionUtils.handleException(e, true, true);
}

You should see a post appear in your Slack channel that details the exception. Below are a few from QA testing the package earlier today.

What are the next steps?

I would love to collect feedback on ExceptionForce, either as comments on this article, via Twitter @RogerMitchell, or as issues on the Github repo. I hope you enjoy playing or working with it!

--

--

Roger Mitchell

Technologist, efficiency creator, iterative innovator; currently @DodgeLabs building apps on @salesforce. Enjoy being outside, cycling, photography, wine.