4

Background: I have worked w/ a consultant to build an Apex rest endpoint, and its working well.

Now I am adding some basic error handling, by putting the insert / update statements into try/catch blocks. If there is an exception, I would like to log it to a custom object. I have a simple utility class that can take an exception and a few optional parameters and it will do the logging.

Question: I've been flummoxed because the error log records are not being created if I throw the exception. Looking in the debug logs I can see that the writetoLog method is being called, and that it rolls back due to a fatal error, which has me thinking that throwing the exception results in the entire transaction being rolled back, including the logging, which I validated on another post on StackExchange.

I found one article on developer.force.com that suggested using a future method to handle the logging - would that address this issue?

I have a hunch that throwing a custom exception might be another alternative, but dont know if that is in fact the case.

So my question is: what are the simplest ways to catch the exception, log it to a custom object, and throw an exception (as else the transaction returns as a success, instead of an error).

The code is below. If I comment out throw e and instead return a string of the error message, the error log is created successfully, so I know there are no underlying permissions issues.

@HttpPost
global static string CreateContact(WebContactData wcd){              
    WebContact__c  wc = TranslateToInternalModel(wcd);
    try{
        Insert wc;
        return wc.Id;
    }catch(exception e){
       utils_logging.writeToLog(e, wcd.FormType, JSON.serializePretty(wcd));
       throw e; 
    }   
}

1 Answer 1

5

Unfortunately if your ending point in the code is throwing an error ALL of the transaction gets rolled back including your log creation. This creates quite the issue.

Future methods also get canceled.

IIRC you CAN make a callout to another restful endpoint that will persist a log entry as long as you have not done DML prior which in unlikely.

What you can do is this though, return a custom response object that the external system can use to determine if there is an error or not. Catch all errors and set the appropriate values in the response object. Modify as needed

@HttpPost
global static myResponse CreateContact(WebContactData wcd){ 
    WebContact__c  wc = TranslateToInternalModel(wcd);
    myResponse res = New MyResponse();
    try{
        Insert wc;
        res.result = wc.id;
        res.isError = false;
    }catch(exception e){
       utils_logging.writeToLog(e, wcd.FormType, JSON.serializePretty(wcd));
       res.isError = true;
    }   
        return res;

}

public class myResponse{
     public boolean isError {get;set;}
     public string result {get;set;}

     public myResponse(){       
     }
}
2
  • 1
    For custom REST Apex, I also recommend setting the status to a non-200 value. This makes it easier to find in clients that log those status values. For example, browsers will highlight 400 errors in the Network log area, and most REST clients will display such errors differently. RestContext.response.statusCode = 400;, for example.
    – sfdcfox
    Commented Jul 31, 2016 at 5:49
  • Thanks custom response setup and looks good. Makes sense as this gives the flexibility to handle as desired and return the desired error code.
    – gorav
    Commented Jul 31, 2016 at 16:05

You must log in to answer this question.

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