I have created a very simple REST service to convert a lead:

global with sharing class RESTLeadConvertController {

    global static Lead getConvertedLead() {
        String leadId = RestContext.request.params.get('leadId');       
        Database.LeadConvert lc = new Database.LeadConvert(); 
        LeadStatus convertstatus = [select Id, MasterLabel from LeadStatus where IsConverted = true limit 1];
        Database.LeadConvert[] lcArray = new Database.LeadConvert[] {lc}; 
        Database.LeadConvertResult[] results = Database.convertLead(lcArray);   
        Lead result = [SELECT Id, email, status, isConverted, convertedAccountId, convertedContactId FROM Lead WHERE Id = :leadId];
        return result;

I've been looking at the best way to provide error handling and send back a success or failure to the consumer. What is the best practice on error handling design for a REST service?


You should use standard http status codes.

You can set status code by setting RestContext.response anywhere before your return statement.

Salesforce will automatically handle most of these. For example, you don't need to handle 401 UNAUTHORIZED as if the request fails authentication, your code will never even be executed.

However, you typically will want to handle additional checks in your own code. Also, IMO, you should return the same standard error response that Salesforce uses for MOST their API endpoints:

  { errorCode: 'NOT_FOUND', message: 'Could not find a match for URL...' }

This makes it much easier for any consuming clients to handle errors.

Another point to consider is that you should avoid using the automatic serialization of return objects and instead set your own JSON response.

This allows you to be more flexible and return different response for success vs failure.


global static void getConvertedLead() {
        Id leadId = RestContext.request.params.get('leadId');
        Lead myLead = [SELECT Id FROM Lead WHERE Id = :leadId];
        //...convert lead
        RestContext.response.responseBody = Blob.valueOf(JSON.serialize(myLead));
    }catch(System.StringException e){
        RestContext.response.statusCode = 400;
        SalesforceError[] errs = new SalesforceError[]{ 
            new SalesforceError('BAD_REQUEST', 'Param: leadId is not a valid Id')
        RestContext.response.responseBody = Blob.valueOf(JSON.serialize(errs));
    }catch(System.QueryException e){
        RestContext.response.statusCode = 404;
        SalesforceError[] errs = new SalesforceError[]{ 
            new SalesforceError('NOT_FOUND', 'Requested Lead not found')
        RestContext.response.responseBody = Blob.valueOf(JSON.serialize(errs));
    }catch(Exception e){ //something else happened
        RestContext.response.statusCode = 500;
        SalesforceError[] errs = new SalesforceError[]{ 
            new SalesforceError('BAD_REQUEST', e.getMessage())
        RestContext.response.responseBody = Blob.valueOf(JSON.serialize(errs));

//standard salesforce error response structure
public class SalesforceError {
    public String errorCode;
    public String message;
    public SalesforceError(String errorCode, string message){
        this.errorCode = errorCode;
        this.message = message;
  • 2
    +1, although a "not found" error would be a 404, not a 500. – sfdcfox Feb 22 '17 at 3:05
  • @sfdcfox good call. Updated – NSjonas Feb 22 '17 at 3:14
  • I don't know if it's a typo, or a new change in the recent sfdc release, but there is no body property in the RestResponse class. Only responseBody is available, and it's a blob. Could you kindly confirm @NSjonas? – SamuelDev Nov 20 '18 at 7:25
  • 1
    @SamuelDev you are corrected. answer updated – NSjonas Nov 20 '18 at 18:06
  • @NSjonas - This doesn't work for me unless I have a return after the catch blocks. Return null returns an empty response body. What do I return after setting the response body? (sorry, I can only post answer. Can't add comment as I am newbie on stackexchange.) – wintri Mar 7 at 11:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.