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?

1 Answer 1


You should use standard http status codes.

You can set the status code on RestContext.response anytime before you return.

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 data API endpoints (composite API is one exception):

  { 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
    Commented Feb 22, 2017 at 3:05
  • @sfdcfox good call. Updated
    – NSjonas
    Commented Feb 22, 2017 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
    Commented Nov 20, 2018 at 7:25
  • 1
    @SamuelDev you are corrected. answer updated
    – NSjonas
    Commented Nov 20, 2018 at 18:06
  • 1
    @RalphCallaway I feel like I have but I can't find any examples. I know the composite API does for sure, but the format is different all together. The reason I recommend following the format above is so that the error response is consistent with circumstances where the request doesn't even make it to your code.
    – NSjonas
    Commented Aug 13, 2019 at 7:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .