Define the Error messages detail in json format as static resource
[{ "id": "REQUESTED_OPERATION_NOT_PERMITTED", "code": 1, "clientTemplate": "the current rest operation is not permitted for this endpoint", "systemTemplate": "the current rest operation is not permitted for this endpoint" }, { "id": "REQUESTED_ID_MISSING_OR_INVALID", "code": 2, "clientTemplate": "id is missing or invalid for the specific request", "systemTemplate": "id is missing or invalid for the specific request Id {0}" }, { "id": "URL_INVALID", "code": 3, "clientTemplate": "url invalid and does not exist", "systemTemplate": "url invalid and does not exist UserId: {0} | Type: {1} | Path: {2} | Body: {3}" }, { "id": "INPUT_JSON_INVALID", "code": 4, "clientTemplate": "the input json provided is invalid", "systemTemplate": "the input json provided is invalid" }]
Define a ResponseCode class to parse the json into a List of ResponseCodes
global with sharing class ResponseCode { public String id { get; set; } public Integer code { get; set; } public String clientTemplate { private get; set { clientTemplate = value; } } public String systemTemplate { private get; set { systemTemplate = value; } } public String formattedClientMessage { get; set; } public String formattedSystemMessage { get; set; } global void formatMessages(List<String> args, Exception ex) { if (args != null && args.size() != 0) { formattedClientMessage = String.format(clientTemplate, args); if (systemTemplate != null) { formattedSystemMessage = String.format(systemTemplate, args); } } else { formattedClientMessage = clientTemplate; formattedSystemMessage = systemTemplate; } if (ex != null) { if (formattedSystemMessage == null) { formattedSystemMessage = formattedClientMessage; } formattedSystemMessage += ' -> Cause by: ' + ex.getTypeName() + ' - ' + ex.getMessage() + '. Cause trace: ' + ex.getStackTraceString(); } } global ResponseCode copy() { ResponseCode theNewObj = new ResponseCode(); theNewObj.id = this.id; theNewObj.code = this.code; theNewObj.clientTemplate = this.clientTemplate; theNewObj.systemTemplate = this.systemTemplate; return theNewObj; } global ResponseCode(){ } global override String toString() { return 'ResponseCode(id=' + id + ';code=' + code + ';clientTemplate=' + clientTemplate + ';systemTemplate=' + systemTemplate + ';formattedClientMessage=' + formattedClientMessage + ';formattedSystemMessage=' + formattedSystemMessage + ')'; } }
Define a ResponseCode Manager to translate the Codes into a map to get by id
public with sharing class ResponseCodes_Mgr{ private static Map<String, ResponseCode> itsResponseCodes = new Map<String, ResponseCode>(); static { try { StaticResource theCodesSrc = [SELECT Id, Body FROM StaticResource WHERE Name = 'ResponseCode' LIMIT 1]; if (theCodesSrc != null) { String theCodesJSON = theCodesSrc.Body.toString(); List<ResponseCode> theCodesList = (List<ResponseCode>) JSON.deserialize(theCodesJSON, List<ResponseCode>.class); for (ResponseCode theCode: theCodesList) { itsResponseCodes.put(theCode.id, theCode); } System.debug('Loaded ' + itsResponseCodes.size() + ' response codes into static map'); } else { System.debug(LoggingLevel.ERROR, 'Cannot query ResponseCode static resource from DB'); } } catch (Exception ex) { System.debug(LoggingLevel.ERROR, 'ERROR loading response codes: ' + ex.getMessage()); } } public static ResponseCode getCode(String anID) { return getCode(anID, null, null); } public static ResponseCode getCode(String anID, Exception anExp) { return getCode(anID, anExp, null); } public static ResponseCode getCode(String anID, List<String> args) { return getCode(anID, null, args); } public static ResponseCode getCode(String anID, Exception anExp, List<String> args) { // make a copy so that the caller can do whatever with the object // multiple callers might use same ID with different args list ResponseCode theCode = itsResponseCodes.get(anID); if (theCode == null) { theCode = itsResponseCodes.get('UNEXPECTED_RESPONSE_CODE').copy(); List<String> theArgs = new List<String>(); theArgs.add(anID); if (args != null) { theArgs.add(args + ''); } theCode.formatMessages(theArgs, anExp); System.debug(LoggingLevel.ERROR, 'Unknown response code ' + anID + '. Returning UNEXPECTED_RESPONSE_CODE and ignoring args list ' + args); } else { theCode = theCode.copy(); theCode.formatMessages(args, anExp); } return theCode; } }
Catch exceptions and log exceptions to logging provide
}catch (JSONException jsonEx){ responseCode = ResponseCodes_Mgr.getCode('JSON_SERIALIZATION_FAILED', jsonEx, new List<String>{UserInfo.getUserId(), requestHeaders.get(TRACE_ID_KEY), requestHeaders.get('timestamp'), requestType.name(), request.requestURI, SHOW_BODY && request.requestBody!= null ? request.requestBody.toString() : ''}); json.setResponseCode(responseCode); } catch (SearchException searchEx){ responseCode = ResponseCodes_Mgr.getCode('SEARCH_FAILED', searchEx, new List<String>{UserInfo.getUserId(), requestHeaders.get(TRACE_ID_KEY), requestHeaders.get('timestamp'), requestType.name(), request.requestURI, SHOW_BODY && request.requestBody!= null ? request.requestBody.toString() : ''}); json.setResponseCode(responseCode); } catch (CalloutException calloutEx){ responseCode = ResponseCodes_Mgr.getCode('CALLOUT_FAILED', calloutEx, new List<String>{UserInfo.getUserId(), requestHeaders.get(TRACE_ID_KEY), requestHeaders.get('timestamp'), requestType.name(), request.requestURI, SHOW_BODY && request.requestBody!= null ? request.requestBody.toString() : ''}); json.setResponseCode(responseCode); } catch (DmlException dmlEx){ responseCode = ResponseCodes_Mgr.getCode('DATABASE_OPERATION_FAILED', dmlEx, new List<String>{UserInfo.getUserId(), requestHeaders.get(TRACE_ID_KEY), requestHeaders.get('timestamp'), requestType.name(), request.requestURI, SHOW_BODY && request.requestBody!= null ? request.requestBody.toString() : ''}); json.setResponseCode(responseCode); } catch (SObjectException sobjectEx){ responseCode = ResponseCodes_Mgr.getCode('SOBJECT_OPERATION_FAILED', sobjectEx, new List<String>{UserInfo.getUserId(), requestHeaders.get(TRACE_ID_KEY), requestHeaders.get('timestamp'), requestType.name(), request.requestURI, SHOW_BODY && request.requestBody!= null ? request.requestBody.toString() : ''}); json.setResponseCode(responseCode); String serializeJson = Rest_Global_Json.instance.serialize(json); res.responseBody = Blob.valueof(serializeJson); } catch (QueryException queryEx){ responseCode = ResponseCodes_Mgr.getCode('QUERY_OPERATION_FAILED', queryEx, new List<String>{UserInfo.getUserId(), requestHeaders.get(TRACE_ID_KEY), requestHeaders.get('timestamp'), requestType.name(), request.requestURI, SHOW_BODY && request.requestBody!= null ? request.requestBody.toString() : ''}); json.setResponseCode(responseCode); } catch (Exception ex){ responseCode = ResponseCodes_Mgr.getCode('REST_DISPATCHER_FAILED', ex, new List<String>{UserInfo.getUserId(), requestHeaders.get(TRACE_ID_KEY), request.headers.get('timestamp'), requestType.name(), request.requestURI, SHOW_BODY && request.requestBody!= null ? request.requestBody.toString() : ''}); json.setResponseCode(responseCode); }