Sep 15, 2015

Stop Drop & Rollback -- How to handle errors properly in Apex/Salesforce with Try, Catch, Rollback Best Practices

Smokey Says - Care will prevent 9 out of 10 Apex errors!
There are some assumptions that we know about when coding in Salesforce in regards to protecting the developer from saving partial-processed data in Salesforce.

- Any exceptions that happen in code(within the same entire execution) will roll back the entire execution so that all database changes leading up to the failure will not be committed to the database.  This is true for triggered code, page controllers, asynchronous code, etc.  This was a GREAT thing as I started developing in Salesforce and really protected the data for the customers.

- The above is only true if: 1. You are not using try/catch blocks around DML operations(which results in undesirable errors on top of standard pages or white-screen error pages from custom pages) 2. Or you are using try/catch blocks and are properly handling the error inside the 'catch'.

There are many uses of try/catch which I won't cover here but you can check that out here.

My Experience

The more custom work I did the more I realized that I was using try/catch all over the place but didn't immediately understand the dangerous implications of using it.  I've talked about this topic many times with other developers, explaining my experience, and it can be a complex one to discuss but I'll try to lay out some hypothetical situations.


  1. You want to use try/catch in a page controller so that you can show a friendly error on the screen for the user.  There are 2 DML operations in the 'button click' action, and say the error happens on the second DML.  So you tell the user there is an issue by adding a pagemessage.  Did you do anything to undo the 1st DML which was a success? Salesforce will not roll-back that DML for you because you've essentially "caught" the error that would have done that.  Result: Bad data. You need to roll-back.
  2. You've got a trigger on Case that will roll-up some custom information to the Account.  This important logic will keep the data in-check.  But sometimes there is an issue when you run the DML Update to the accounts, so you wrap the DML in a try/catch and perform a system.debug to figure things out a bit better.  You've deployed things like this to production since it is very rare.  By "catching" this error and the only handling you've done is a debug, you have told Salesforce not to roll-back the changes to the original Cases that fired the trigger.  You'll end up with Cases(newer changes) out of sync with Account(failed update) in your database.  The solution is that you need to attach a ".adderror()" to the appropriate Case records in the trigger which will tell salesforce to roll-back changes and will show your custom more descriptive error to the user(or to the calling code / external system). Result: Bad data. You need to .addError

Code Examples - VF Controller

VF Controller Good Example no try/catch - Standard exception handling, SF handles database protection KEY: Do nothing extra (Good)

VF Controller Bad Example with try/catch - Account will insert without the case
Since we are using try/catch below, we are able to show the user a nicer error message with the ApexPages.addMessage method. BUT, we are now taking over the standard salesforce pattern of "error and rollback". And we are forgetting to rollback ourselves.

VF Controller Good Example with try/catch - If Case fails, Account insert will rollback KEY: Using Database Rollback (Best Practice)

Code Examples - Trigger

Trigger Good Example no try/catch - Standard exception handling, SF handles database protection KEY: Do nothing extra (Good)

Trigger Bad example with try/catch - Account update could fail but we didn't stop the Cases from being inserted

Trigger Good example with try/catch - If Account update fails, we flag the Cases with an error which will show to user and prevent the Case inserts KEY: Use .addError() method (Best Practice)

Other Tips

- When using the generic exception class, it will catch any type of error besides for limits and some other situations. Be careful not to put too much inside the same Try block as it'll be more difficult to figure out what caused the error. Best practice would be use specific exception classes like dmlexception and only put a single DML in that try block.

- Make sure to test your catch blocks.  In your manual tests you can configure a dummy "requirement" on an object or a validation rule you know will fail, or leave out a required field. Then attempt the custom button, standard button, whatever it is that starts the code which should fail and see how your catch block operates.  For unit tests this could be more difficult but you could employ some special logic to conditionally fill in data or fail to fill in data in your code.  Say your controller would be looking for "Unit Test *** Fail DML Required Field" it could know to purposely clear a field on a record before the DML which would then fire your catch block.  Or you have a Unique field setup in an object and let your unit test try to insert 2 records with the same values in that field.  There's many other things you could do, up to you.

Dreamforce '15 Session: Enhanced Web Service Testing: A Better Mock Structure

Session Title: Enhanced Web Service Testing: A Better Mock Structure

When: Tuesday, 9/15/15 at 5:30 PM
Where: Moscone West - 2007

Salesforce provides an interface for testing callouts named HttpCalloutMock used to cover remote callouts. While adequate for simple callouts, in the real world you often need something more flexible, as in the case of multiple and varying responses from the same or varying endpoints. More precise testing and coverage can be obtained by extending the standard interface. Join us as we demonstrate a solution to use to enable the flexibility required for complex integration and synchronization apps.

Unmanaged Package:
Original Blog Post:

Sep 8, 2015

Lab Coat Challenges: Challenge #5 Now Available

Challenge 5: Magic 8 Ball

Hey developers (and budding developers)!

Dreamforce is next week!  Who saw that coming?  If you follow us on Twitter (@crmscience), you probably did. #CalendarCube.

Being next week, you might be strategizing when you're going to get your selfie in with SaaSy.  With this week's challenge, we wanted to give you a way to wake up in the morning and definitely have an answer for "Will I see SaaSy today?"
You'll be creating a magic 8 ball like method that returns a string.  This magic 8 ball, though, only answers one question... "Will I see SaaSy today?"  You know, because a Dreamforce without a SaaSy selfie is like eating a cupcake without icing.

Within the method, determine how to randomly select return one of the valid answers.

Click here for the full details, rules, and starter code!

Sep 7, 2015

Lab Coat Coat Challenges: Challenge #3 Responses!

Great round of submissions for this Lab Coat Challenge!

It's interesting to see how everyone had a similar approach to resolving the problem and used different tools to get there. Some were able to create concise solutions that made use of system methods while others ended up replicating the same work or something very similar. Great example of where it pays to know (or, minimally know they exist) some of the more rarely used methods in the documentation.

Thanks to everyone who has participated so far and for those that are checking these answers out now and think they can do better!  Keep the submissions coming and we hope you're enjoying these challenges!

Link:  Lab Coat Challenges

Starter Code

Asserts for all code













Sep 1, 2015

Lab Coat Challenges: Challenge #4 Now Available

Challenge 4: Get Crackin'

Hey developers (and budding developers)!

Think you're pretty saavy when it comes Salesforce?  Demonstrate your mastery of the platform and earn the best badge possible - an honorary CRM Science lab coat!

The last challenge had you thinking with a particular mindset.  This week is a bit of a continuation of that.

k == a

Programmatically determine how k relates to a and use that knowledge to decrypt the following string:

Click here for the string!

Aug 25, 2015

Lab Coat Coat Challenges: Challenge #2 Responses!

Responses are in!

Just like our first challenge, the second had a lot of great submissions. A few common approaches early in the week and a few revisions later after we issued a "Can you do it in a single FOR loop" sub-challenge.

Again - If you haven't had a chance to submit your answer for this challenge OR you think you can improve upon the answers below, please do!









Aug 23, 2015

Lab Coat Challenges: Challenge #3 Now Available

Challenge 3: As Easy as A to B

Hey developers (and budding developers)!

Think you're pretty saavy when it comes Salesforce?  Demonstrate your mastery of the platform and earn the best badge possible - an honorary CRM Science lab coat!

It's back to school already for a lot of young developers out there.  We though this would help them recall some of that knowledge that might have been lost over the summer. 

A... B... shoot, what comes next?

This week's challenge is all about finding the easiest way to increment characters.  How do you increment a string that is set to "A" to "B?"  How about "S" to "T" and so on?

If only if it were as simple as "A" + 1.  Or is it?

In the sample code, you'll be providing the body of a method that accepts two parameters:
  • Letter - a string of a single letter that you'll be incrementing
  • Step - an integer to control how far many steps the starting letter should be shifted.
Up to the challenge?  Review the rules, full details and starter code here!

Aug 19, 2015

Lab Coat Coat Challenges: Challenge #1 Responses!

Responses are in for our first Lab Coat Challenge!

We had some great responses over the last week from several Salesforce devs!  If you haven't had a chance to submit your answer for this challenge OR you think you can improve upon the answers below, please do!

While all technically were valid answers, submissions generally fell into a few camps; those with structure that could be used and extended beyond the example strings and collections provided, those that would only work with the examples given, and those just being..."slick."  We'll call it "slick" and leave the interpretation to you...

Early in the week, no two answers were the same.  By the end of the week, we had several that made use of the list.addAll() method.  Others techniques included various ways of pre-populating lists and even various string manipulations.

All code started with the following...

All code was verified using...

So let's take a look at some of the responses!

Note:  Some code might have been modified up for readability.






Dan Kelner



CRM Science Responses


When we started preparing these challenges, I wanted to be sure to be able to provide an answer for each. So how did I approach it? Dynamically, of course!


Tom Miller

Aug 16, 2015

Lab Coat Challenges: Challenge #2 Now Available

Challenge 2: Reversing Text

Hey developers (and budding developers)!

Think you're pretty saavy when it comes Salesforce?  Demonstrate your mastery of the platform and earn the best badge possible - an honorary CRM Science lab coat!

Challenge #2 is a simple task!  Turn "eeS uoy ta !ecrofmaerD" into "See you at Dreamforce!"  See what we did there?   How few statements do you need?

Up to the challenge?  Review the rules, full details and starter code here!

Aug 7, 2015

Lab Coat Challenges: Challenge #1 is Up!

Introducing the CRM Science Lab Coat Challenges!

Hey developers!

Think you're pretty saavy when it comes Salesforce?  Demonstrate your mastery of the platform and earn the best badge possible - an honorary CRM Science lab coat!

Challenge #1 is all about working with collections and doing so as efficiently as possible.  The gist is you have a few strings, few lists of strings, few sets of strings, and it's up to you to merge them all down into a single list of strings, using as little code as possible.

Up to the challenge?  Get the full details here!

Jun 27, 2015

How to Abort a Scheduled / Queued Apex Job by Name

For the advanced salesforce developers out there.... in the past (before Winter 14 release) there was no way to query for a Scheduled, Future, or Batch job by the name that was given to it. You had to track the ID of the job as the job was being created and store this into a custom object or setting for future reference.

Thanks to a feature from Winter 14 which stemmed from this idea, you can easily query the CronTrigger object filtered by the job name.  Remember to increase your API version in your class if this does not work.

Now we can query for the apex job by name and perform a system.abortjob with confidence that we have the correct job.

Here is a nice block of code that can be used in your application or something to keep handy for an Execute Anyonymous situation.

Jun 9, 2015

This change set requires the "##.#" or later platform version

It's that time of the year again (one of three times, actually), where you might be attempting to make some fixes in a sandbox that has already been upgraded to the next release and uploading a Change Set from that org to Production where the next release hasn't been applied yet.

This change set requires the "##.#" or later platform version

  • Sandbox 1: Summer '15
  • Production: Spring '15

By chance, did you get to this point by following a normal deployment pattern? You know, where you deploy from a developer sandbox to a full sandbox and are now ready to deploy to Production? 

Chances are, the full sandbox you deployed to was also upgraded to the next release. You probably already know that upon upload, a Change Set's components are locked down. But did you also know that the API version of that Change Set is set and locked based on the target org's API?

This means that when you uploaded from your developer sandbox to the full sandbox, the Change Set was set to the latest API version and is now locked to it. When you attempt to upload this same Change Set to production, you get the "This change set requires..." error message.

Out of luck? Nope! Just "Clone" the Change Set and re-upload.

When you create a new Change Set by cloning, you're creating a new instance of the Change Set with all the original components and is unlocked so new components can be added.  At this point, the API number has yet to be set as well.

This time, don't upload to a sandbox first; upload it directly to Production so the Production org's API number is set on the Change Set and the upload is allowed.

Jun 8, 2015

User Level Visualforce UI Control w/ Custom Permissions


As you are developing a Visualforce interface for users to interact with, you may find that certain form elements (panels, links/buttons, etc) may or should not apply to certain users.  Standard Salesforce user control can prevent users access to a specific page, objects, tabs, or other larger components without allowing much flexibility for the occasional granularity you need.

Sample Scenario

The objective below is to develop a page which offers four command buttons to perform four different actions (Purchase Media, Create Media, Borrow Media, and Rate Media) in a library environment.  In this library environment, there are three different groupings of users (listed in order of privilege); those will complete and full access, librarians, and borrowers.  Full access will be able to perform all actions, librarians can do all but purchase media, and borrows can only borrow and review media.


  • User Object Custom Fields:  You could create boolean toggles/checkboxes or minimally a multi-select picklist to allow org Admins to designate access on a per user level.  Downsides are that you're creating a field(s) and it leaves room for admin error (what was it... librarians can purchase or not?).  There's also the cost of querying for these fields via SOQL against the context's execution.  The fields could be included in a package, but would require post-installation configuration (maybe a post-install script to default all).
  • Custom Settings:  You could also create a Custom Setting of the hierarchy type, but still room for admin error.  On the pro-side, Custom Settings are cached and easily accessible via system methods, so it won't count against your SOQL queries.  Can also be included in a package and require the same post-install configuration or defaulting through a post-install script.
  • Custom Permissions:  Depending on your usage, these may or may not count against your SOQL limits.  Management is much easier as you can group individual permissions into a larger Permission Set and then apply the Permission Set(s) to a user.  Now all an Admin has to do is remember which Permission Set to apply to user(s).  Like the other two, can also be included in a package.  They also have the unique benefit in that they can be used to provide custom permissions to users authenticating in Connected App.

Custom Permissions 

We'll be checking out Custom Permission creation, assignment, and usage in the samples below.  To do so, we'll build a Visualforce page with four buttons, one for each possible permission, as well as show two page block sections that show which permissions the current user has.  One page block section will use the $Permission global variable to make that determination straight from Visualforce without a controller (see "Global Variable Way" below) and the other page block section will use Apex to determine applied permissions (see "sObject/SOQL Way").

Here's the end result:

Before we get to the good stuff, let's see how to create the Custom Permissions and get them applied to a User first...

Creating Custom Permissions

  1. Navigate to Setup --> Build --> Develop --> Custom Permissions

  2. Click on the "New" button and provide the various details about your Custom Setting.  The thing to remember here is it's up to you to determine what this "permission" stands for - at the end of the day, it's just a name that stands for a single or multiple privileges/abilities for a user to do thing.  In this example, anything within our Custom App involving the borrowing of books should refer to this setting.

Assigning Custom Permissions to Permission Sets

  1. Navigate to Setup --> Administer --> Manage Users --> Permission Sets

  2. Click on the "New" button, provide the required details about your permission set, and then click on the "Save" button.

  3. Within the "Apps" section, click on the "Permission Sets" link

  4. Select the appropriate permissions and then click on the "Save" button

Assigning Permission Sets to Users

  1. Navigate to Setup --> Administer --> Manage Users --> Users

  2. Click on the name of a User

  3. Within the User's Related Lists, hover over "Permission Set Assignments" and click on the "Edit Assignments" button

  4. To apply a Permission Set and its related Custom Permissions, move the Permission Set from the "Available Permission Sets" column to the "Enabled Permissions Sets" column.

Using Customer Permissions

With the creation and assignment out of the way, let's look at how we can use them to control Visualforce UI elements based on their assignment.  

Global Variable Way

Directly from Visualforce, it's as easy as...

Here's an example from the full VF page:

sObject/SOQL Way

We need to access several objects.  First we'll need to query for all CustomPermissions.  Then we'll query for SetupEntityAccess records that apply to the current user based on PermissionSetAssignments - see snippet below.  In the full sample, I've set up a set<string> called LibraryPermissions that will contain the DeveloperNames of CustomPermissions applied to the current user.  I'll also create a method to return string.valueOf(LibraryPermissions) so the Visualforce page can just use CONTAINS(LibaryPermissionsStr, 'the permission I want to check').

Apex Snippet (full code at bottom)

VF Usage

Practical Usage

Showing the permissions is one thing, but using Custom Permissions in a practical way that helps you control UI elements is another.  Using either technique, we can show/hide buttons that apply to that user according to the Permission Sets applied.

Here's a quick snippet of  rendering commandButtons accordingly:


So there we go!  We've effectively modified a UI by leveraging the semi-new Custom Permissions and demonstrated how they can be created, applied to a User through the use of Permissions Sets.  While showing/hiding buttons isn't too glorious of an example, we'd love to hear how you use them in the comments or on Twitter @crmscience!

Apr 25, 2015

Generically Calling External Classes from Managed Packages

Let’s say that you’re building a managed package but one of the target orgs for the package needs some custom logic to execute in the middle of your package logic or perhaps fork into completely different path that is not common to the rest of the orgs that install your package. Let’s say that you have two or three of these “special” orgs that are a minority of the package installs but important enough to handle. Here’s one way to handle such craziness...

The goal of this exercise is to be able to have the target org tell your package that there is some custom code that needs to be executed. We need a way to do this dynamically, and have it controlled by the target org. That feat can be achieve with a custom setting, an interface class, and dynamic class instantiation.

First, you’ll need to create a non-protected custom setting in your managed package. The custom setting is pretty simple, and contains the following text fields:
  • Name - the standard Name field is used to get the values if a specific forking may be needed at specific times.
  • ClassName__c - used to hold the name of the external class that needs to be called.
  • Namespace__c - used to hold a namespace in case the external class is located in a different extension package.

Now that we have a way for the target org administrator to alert the package code that an external class needs to be called, we need to handle that in the package code itself. We’ll first Create Interface class and a method that is so generic, that it can be used with any number of parameters and can get a response that includes any response type. We do that by setting the return variable and the class parameter to the object data type, which can be casted to any type of other data type. That will allow different implementations to use this class in completely different ways.
Now that the interface class is ready, it can be used in strategic locations around the code to call external classes as needed. If you need some added flexibility and have no fear, you can also blindly execute anything you can find in the custom setting. That can be done by instantiating an instance of the external class by dynamically instantiating the interface class, which provides a concrete type that can be instantiated. Note that you’ll need to make sure that you use the namespace in the forName method if you are pointing to a class in an external package.
The code is now done and a new release of the managed package can be created. The only thing left to do is to use the new code from outside the package. You do that by creating a class in the target org or an extension package that implements the base package interface. Parameters that are sent into this class go by the normal apex rules, so maps and lists that are passed can be manipulated in the external class (passed by reference). Since the interface blueprint is flexible, the implementation can be static in case a callout needs to happen (needs to be static in some cases because a trigger starts the execution).

Apr 2, 2015

Salesforce1 Mobile - Fun with IFrames & Matching the Styling

When you start developing for mobile, you tend to find reasons for harnessing the device features that they come with (camera, location services).  If you've ever had the need to snap a photo from Salesforce1 and attach it to a record(in a custom VisualForce page of course), you may have come across the wonderful tag <apex:InputFile />.  It's a definite time-saver versus having to handle the complexities of file formats, sizes, viewstate, governor limits etc.

My guess is that you've also ran into issues when trying to rerender a part of this visualforce page, or perform an "oncomplete" action.  You would get this error if so:

apex:inputFile can not be used in conjunction with an action component, apex:commandButton or apex:commandLink that specifies a rerender or oncomplete attribute

This means that any other part of the page that attempts one of these actions will not be able to do so, simply because the page contains an InputFile tag elsewhere.  I quickly found this solution (using an ActionRegion tag to wrap other parts of the page) that worked initially but as my page grew, the InputFile component broke. The component stopped firing the setter for my Attachment property.  The more I worked with trial and error, I decided to cut my losses and encapsulate it within an iframe so that I could code with freedom on the main page.

It figures that I would find other solutions AFTER taking my plunge into this solution, but it was fun, and I can use this in other ways :)!  Here are other options to using Apex:InputFile tags in more complex situations:

A solution to divide the pages:

  1. Attachment page: Create a page that takes an ID as a url parameter for the ParentId, to be used to insert the attachment. In this page you have the InputFile tag which handles the file. 
  2. Parent page: Show the attachment page in an IFrame. Use javascript functions that can be fired between the child and the parent windows for a seamless user experience however you see fit. (same domain).

Link: Demo

  1. This works in all browsers.
  2. The demo site was built for Salesforce1 and is a great example of using Bootstrap SF1 Theme along with the standard Bootstrap Javsascript library (matching the version to 3.0.1).
  3. The demo is responsive and works in the Salesforce1 app on mobile devices, desktop, and Salesforce1 through the browser.
  4. Other improvements would be
    1. Implement swipe for the Details and Attachments tabs, and convert to "tap" instead of "onclick" events. 
    2. Best Practice: Use JS remoting and remove the view state for better mobile performance.  Implementing remoting on the parent page could be done with this iframe solution being handy.

Link: GitHub

Keys to the solution:

AccountDetail page
  • Contains an IFrame with id = "attachmentIFrame"
  • Contains the submit button as part of the modal. It fires a javascript function from within the iframe to insert the attachment.
  • Contains a close button which is unlimited and able to call an actionFunction which does contain an oncomplete rule (which navigates the user to the attachments tab list).

AttachmentUpload page
  • Contains the Apex:InputFile tag, and has an accessible javascript/actionFunction called "processAttachment". This is the function that the parent page will call.

AttachmentUpload class
  • Contains page accessible method "ProcessAttachment" which will take the attachment property and perform the DML insert.

Salesforce1 & other Goodies:

  • Salesforce1 navigation vs desktop navigation are different, see this JS function than helps to handle this (used here when clicking on a link to the attachment).

  • When the user clicks the Close button after they uploaded the attachment(s), we are able to show the Bootstrap tab very easily.

By separating the inputFile tag, you can use rerender or oncomplete attributes on the parentpage again, without the need for actionRegion tags or multiple Form tags.

Styling is done with the BootstrapSF1 package and the Bootstrap Javascript library to match. This will work in Salesforce1.

Jan 16, 2015

Managing SFDC Credentials Using KeePass

Fun Fact:  The longer you work with the Platform the more sets of credentials you are going to have to maintain.

I should invest in a tally click counter to keep track of the number of times I log into various (and often the same) Salesforce orgs throughout the day.  At a certain point, to maintain your sanity, you need some sort of assistance to keep track of all your Salesforce org details.
  • Username
  • Password
  • Token
  • URL - login, test, etc
  • Org Type - Group, Professional, etc
  • Notes about the org's purpose - Dev Org for XYZ Project
Now, I've used the Logins Chrome extension for the last few years to help keep track of a few of those items as well as to help pop-open a new session in a new window, tab, or Incognito session.

While it's easy to search, it seemed to be growing unmanageable recently; the list was growing longer and I had a lot of old/stale entries.  

There were also a few long standing drawbacks:
  • Credentials are stored via Chrome's local storage as opposed to sync storage, meaning the credential data, an XML structure, stayed on one computer and wasn't replicated across all of my devices where Google's sync normally applies.  By day, I'm often on one computer, which frequently requires updates to these credentials.  By night, I'm on another computer and let's face it... getting up off the couch after a long day to retrieve your token from another computer's not going to happen.  Entire data dupe nightmare.
  • Logins is a Chrome extension, so while I can open Chrome tabs, windows, and Incognito tabs just fine, sometimes you want or need a Firefox or Internet Explorer window.  There's a Firefox version (don't know if it is associated with Appirio or not), but I had trouble exporting my Chrome extension credentials and importing them into the Firefox verison.
So, what to do?  There's all kinds of password managers out there.  LastPass and 1Password are two great examples.  Check out LifeHacker's Top Five Best Password Managers list to get a better feel for what they to.

In a previous life, before the cloud was "the cloud," I managed various systems credentials via an application called KeePass.  KeePass is a free, open-source program that allows you to create, organize, and store your various credentials in a local database, a .kdbx file.  You can keep this encrypted database on your hard drive or flash drive and use it to store endless hierarchies of credentials for all of your commonly visited websites, including Salesforce.  

I can quickly overcome both of those drawback bullet points above with KeePass:
  • While the .kdbx file the stores all of your passwords is saved to your computer, there's nothing preventing you from storing the file in a Dropbox folder.  Sync that folder across your devices and never be left without your credentials again.
  • Being open-source, there's various Chrome Extensions, Firefox add-on, and Internet Explorer... I don't even know what you call them... thingamabobs... that connect your browser to the KeePass program running in your system tray.  This can provide a list of credentials for the website you're currently visiting or an auto-population of creds, if you want.  
There's some additional perks too:
  • I don't have to rely on those extensions, add-ons, and thingamabobs.  I can customize KeePass to have custom buttons to open a browser of my choice, in the standard mode or Incognito/Private mode, and automatically log into Salesforce for me - replicating the functionality of the Logins Chrome Extension, but allowing me to use the browser of my choice.
  • There are global keyboard shortcuts (CTRL+ALT+K) that allow me quickly find my credentials and get logged in, without taking my hands off the keyboard.
  • There's an "AutoType" feature that allows me to assign a shortcut key to the selected credential entry that will take fields from my credential (username, password, url, custom - oh, did I mention the ability to create custom fields for additional data your token?) and automatically type that string into another window for you.  Admins and Developers - how many times do you have to type in your password, go look up what your latest security token is and then copy/paste it after your password for new Data Loader sessions or IDE projects?  Imaging highlighting your credential, pressing a set of keys and letting the program do the work for you.
Ok great.  It does a lot, solves my problems, but is it going to help you?  Maybe, give it a shot.  This approach of auto-logging you into a Salesforce org is no more secure than the Logins extension and it is very possible your credentials could be seen within your browser history or URL bar upon login.  Check out the review of the Logins extension for plenty of feedback about that.

The rest of this blog post will be to demonstrate how to:

1)  Set up a new KeePass Database
2)  Add a  Group
3)  Add an Entry
4)  Include a custom Token field
5)  Set up KeePass Trigger Buttons
6)  Create/Assign KeePass Trigger Actions to open creds in the browser and mode of your choice.

Set Up a New KeePass Database

1)  The first thing you'll want to do is install the program from KeePass and open it up.
2)  Click on File --> New... to create a new database.  Give it a name and save it in a location of your choice.  This is where I save my file to my synced Dropbox folder.  Once you save it, you always have the ability to rename and move the file.

3)  Next, you'll create a master key.  Pick a strong phrase that you won't forget.  At this point, you can also create an additional key file to store separately (maybe on a USB), that you'll need to provide in addition to you database and master key for some extra security.

 4)  Within the Database Settings screen, you can provide a name and description for your credential database.  Check out the other tabs for more security and a few other storage related settings.

Add a Group

1)  Now that you're database is created, you can start structuring your credential folders to stay organize.  You can create a top-level "Salesforce" folder and then create sub-folders for clients, projects, etc.  Do this by going to Edit --> Add Group.

Add an Entry

1)  Now you can start populating your entries.  Click on Edit --> Add Entry... and provide details about your credentials.  Here I provide a quick Title (label) for the cred, usually something along the lines of "Testing:  Feature X" or "Development Org:  Feature X."  To take advantage of the browser abilities we'll be using later, be sure to provide either the login or URL in the appropriate field.  There's a few different ways to skin-this cat, but using the URL field will also allow you to auto-fill/suggest credentials if you use one of the various KeePass related browser add-ons.

 2)  Click on the "Advanced" Tab, followed by the "Add" button to add a new custom string field.

3)  Give it the name "Token" (be consistent about this) and then paste your security token in the "Value" box.

KeePass Triggers


Nope, not Apex Triggers, KeePass triggers.  KeePass triggers are a way that you can create your own custom features within KeePass, without any development.  We'll be creating two triggers, one a button, and one an action for when the button is clicked.  That functionality will be opening the browser of your choice, in standard or private mode, and logging into Salesforce with the credentials you have highlighted.

If you configure all the browsers, this is what you'll end up with these triggers:

Which will result in these custom buttons within the tool:

Creating the Buttons

1)  Go to Tools --> Triggers...
2)  Provide a name for this trigger.  I prefix mine with "Button:  " just to keep them straight in the list.

3)  Go to the "Events" tab, click on the "Add..." button

4)  Choose the "Application started and ready" option.

5)  Leave the "Conditions" Tab blank.

6)  On the "Actions" Tab, click on the "Add..." button.

7)  Within the "Action:" dropdown, choose "Add custom toolbar button.  Then provide an ID, Name, and Description for this new button.  The Id is important as this will be referenced by the next trigger you create.

Assigning an Action to a Custom Button

1)  Create another trigger, providing a name for it on the "Properties" tab.  This time, I prefix the name with "Action:  "

 2)  On the "Events" tab, click on the "Add..." button

3)  From the "Event:" dropdown, choose "Custom toolbar button clicked" and next to "ID" provide the ID of the button to be clicked (you defined this in the above step 7).

 4)  Again, leave the "Conditions" tab empty.

 5)  On the "Actions" tab, click on the "Add..." button.

 6)  From the "Action:" dropdown, click on the "Execute command line / URL" option.  Provide the following as parameters for the "File/URL" and "Arguments" options.  Here we're using the equivalent of Salesforce merge fields to populate the setting with a value from the credential.

Arguments:  {URL}?un={USERNAME}&pw={PASSWORD}

Now when you open KeePass, you'll have a few additional buttons within the programs toolbar for you to use.
1)  Highlight the credential you want to use
2)  Click on the appropriate custom toolbar button to get logged into Salesforce

Update #1 - 1/22/2015

About a week into using this over the Plugins extension and I've adapted well.  The extension is gone and my habit to click there is gone.

The process is easy:
Ctrl + Alt + K opens KeePass
Ctrl + F opens the search prompt
And I'm off!

Here are the URLs and the arguments that I used for my six buttons; two for each browser (Chrome, Firefox, and Internet Explorer).  One for normal browsing and one for that browser's private mode.

Google Chrome - Standard
Arguments:  {URL}?un={T-CONV:/{USERNAME}/Uri/}&pw={T-CONV:/{PASSWORD}/Uri/}

Google Chrome - Incognito
Arguments:  -incognito {URL}?un={T-CONV:/{USERNAME}/Uri/}&pw={T-CONV:/{PASSWORD}/Uri/}

Firefox - Standard
Arguments:  {URL}?un={T-CONV:/{USERNAME}/Uri/}&pw={T-CONV:/{PASSWORD}/Uri/}

Firefox - Private Mode
Arguments:  {URL}?un={T-CONV:/{USERNAME}/Uri/}&pw={T-CONV:/{PASSWORD}/Uri/} -private-window 

Internet Explorer - Standard
Arguments:  {URL}?un={T-CONV:/{USERNAME}/Uri/}&pw={T-CONV:/{PASSWORD}/Uri/}

Internet Explorer - Private Mode
Arguments:  {URL}?un={T-CONV:/{USERNAME}/Uri/}&pw={T-CONV:/{PASSWORD}/Uri/} -private 

Update #2 - 6/27/2015
I've modified the scripts to work a little bit better with things like special characters; previously if a username/password contained things like "+" symbols (who doesn't use the Gmail alias trick?) the buttons would not work as desired.

The work around is to modify the above snippets to take advantage of the KeePass text transformation {T-CONV}.  each argument has been updated above.

Looking to save some time setting these up?  Copy the following gist to your clipboard and then navigate to Tools --> Triggers... "Tools" button in the lower-left --> and then click on the option to "Paste Triggers from Clipboard."  Then restart KeePass.