Responses and Exceptions
All SDK methods return an instance of the APIResponse class.
After a successful API request, the getObject() method returns an instance of the ResponseWrapper (for GET) or the ActionWrapper (for POST, PUT, DELETE).
Whenever the API returns an error response,the getObject() returns an instance of APIException class.
ResponseWrapper (for GET requests) and ActionWrapper (for POST, PUT, DELETE requests) are the expected objects for Zoho CRM API's responses.
However, some specific operations have different expected objects, such as the following:
Operations involving records in Tags
-RecordActionWrapperGetting Record Count for a specific Tag operation
-CountWrapperOperations involving BaseCurrency
-BaseCurrencyActionWrapperLead convert operation
-ConvertActionWrapperRetrieving Deleted records operation:
-DeletedRecordsWrapperRecord image download operation
-FileBodyWrapperMassUpdate record operations
-MassUpdateActionWrapper
-MassUpdateResponseWrapper
For GET Requests
The getObject() returns an instance of one of the following classes, based on the return type.
For application/json responses
- ResponseWrapper
- CountWrapper
- DeletedRecordsWrapper
- FileBodyWrapper
- MassUpdateResponseWrapper
- APIException
For file download responses
- FileBodyWrapper
- APIException
For POST, PUT, DELETE Requests
The getObject() returns an instance of one of the following classes, based on the return type.
For application/json responses
- ActionWrapper
- RecordActionWrapper
- BaseCurrencyActionWrapper
- MassUpdateActionWrapper
- ConvertActionWrapper
- APIException
These wrapper classes may contain one or a list of instances of the following classes, depending on the response.
- SuccessResponse Class, if the request is successful.
- APIException Class, if the request is erroneous.
For example, when you insert two records, and one of them was inserted successfully while the other one failed, the ActionWrapper will contain one instance each of the SuccessResponse and APIException classes.
All other exceptions such as SDK anomalies and other unexpected behaviors are thrown under the SDKException class.
SDK Sample code
class Record {
static async call() {
/*
* Create an instance of Logger Class that takes parameter
* 1 -> Level of the log messages to be logged. Can be configured by typing Levels "." and choose any level from the list displayed.
*/
let logger = Logger.getInstance(Levels.ALL);
/*
* Configure the environment
* which is of the pattern Domain.Environment
* Available Domains: US, EU, IN, CN, AU
* Available Environments: PRODUCTION(), DEVELOPER(), SANDBOX()
*/
let environment = DataCenter.US.PRODUCTION();
/*
* Create a Token instance
* clientId -> OAuth client id.
* scope -> OAuth client scope.
* redirectURL -> OAuth Redirect URL.
*/
let token = new OAuthBuilder()
.clientId("clientId")
.scope("scope")
.redirectURL("redirectURL")
.build();
/*
* autoRefreshFields
* if true - all the modules' fields will be auto-refreshed in the background, every hour.
* if false - the fields will not be auto-refreshed in the background. The user can manually delete the cache or refresh the fields using methods from ModuleFieldsHandler
*
* cacheStore
* A boolean field that allows or disallows the storage of module field information in cache.
* True - the SDK stores all the modules' field information in cache, and refreshes every hour, if autoRefreshFields is true.
* False - the SDK temporarily stores the modules' field information in a Map.
*
* pickListValidation
* A boolean field that validates user input for a pick list field and allows or disallows the addition of a new value to the list.
* True - the SDK validates the input. If the value does not exist in the pick list, the SDK throws an error.
* False - the SDK does not validate the input and makes the API request with the user’s input to the pick list
*
* timeout
* representing the number of milliseconds a request can take before automatically being terminated.
*/
let sdkConfig = new SDKConfigBuilder().autoRefreshFields(true).pickListValidation(false).cacheStore(true).build();
/*
* Call the static initialize method of Initializer class that takes the following arguments
* environment -> Environment instance
* SDKConfig -> SDKConfig instance
* token -> Token instance
* logger -> Logger instance
*/
(await new InitializeBuilder())
.environment(environment)
.token(token)
.SDKConfig(sdkConfig)
.logger(logger)
.initialize();
await Record.getRecords();
}
static async getRecords() {
//Get instance of RecordOperations Class
let recordOperations = new ZCRM.Record.Operations();
//Get instance of ParameterMap Class
let paramInstance = new ParameterMap();
/* Possible parameters for Get Records operation*/
await paramInstance.add(ZCRM.Record.Model.GetRecordsParam.APPROVED, "both");
await paramInstance.add(ZCRM.Record.Model.GetRecordsParam.CONVERTED, "both");
await paramInstance.add(ZCRM.Record.Model.GetRecordsParam.SORT_BY, "Email");
await paramInstance.add(ZCRM.Record.Model.GetRecordsParam.SORT_ORDER, "desc");
await paramInstance.add(ZCRM.Record.Model.GetRecordsParam.PAGE, 1);
await paramInstance.add(ZCRM.Record.Model.GetRecordsParam.PER_PAGE, 200);
//Get instance of HeaderMap Class
let headerInstance = new HeaderMap();
/* Possible headers for Get Record operation*/
await headerInstance.add(ZCRM.Record.Model.GetRecordsHeader.IF_MODIFIED_SINCE, new Date("2020-01-01T00:00:00+05:30"));
//Call getRecords method that takes paramInstance, headerInstance and moduleAPIName as parameters
let response = await recordOperations.getRecords("Leads");
if (response != null) {
//Get the status code from response
console.log("Status Code: " + response.getStatusCode());
if ([204, 304].includes(response.getStatusCode())) {
console.log(response.getStatusCode() == 204 ? "No Content" : "Not Modified");
return;
}
//Get the object from response
let responseObject = response.getObject();
if (responseObject != null) {
//Check if expected ResponseWrapper instance is received
if (responseObject instanceof ZCRM.Record.Model.ResponseWrapper) {
//Get the array of obtained Record instances
let records = responseObject.getData();
for (let index = 0; index < records.length; index++) {
let record = records[index];
//Get the ID of each Record
console.log("Record ID: " + record.getId());
//Get the createdBy User instance of each Record
let createdBy = record.getCreatedBy();
//Check if createdBy is not null
if (createdBy != null) {
//Get the ID of the createdBy User
console.log("Record Created By User-ID: " + createdBy.getId());
//Get the name of the createdBy User
console.log("Record Created By User-Name: " + createdBy.getName());
//Get the Email of the createdBy User
console.log("Record Created By User-Email: " + createdBy.getEmail());
}
//Get the CreatedTime of each Record
console.log("Record CreatedTime: " + record.getCreatedTime());
//Get the modifiedBy User instance of each Record
let modifiedBy = record.getModifiedBy();
//Check if modifiedBy is not null
if (modifiedBy != null) {
//Get the ID of the modifiedBy User
console.log("Record Modified By User-ID: " + modifiedBy.getId());
//Get the name of the modifiedBy User
console.log("Record Modified By User-Name: " + modifiedBy.getName());
//Get the Email of the modifiedBy User
console.log("Record Modified By User-Email: " + modifiedBy.getEmail());
}
//Get the ModifiedTime of each Record
console.log("Record ModifiedTime: " + record.getModifiedTime());
//Get the list of Tag instance each Record
let tags = record.getTag();
//Check if tags is not null
if (tags != null) {
tags.forEach(tag => {
//Get the Name of each Tag
console.log("Record Tag Name: " + tag.getName());
//Get the Id of each Tag
console.log("Record Tag ID: " + tag.getId());
});
}
let keyValues = record.getKeyValues();
let keyArray = Array.from(keyValues.keys());
for (let keyIndex = 0; keyIndex < keyArray.length; keyIndex++) {
const keyName = keyArray[keyIndex];
let value = keyValues.get(keyName);
console.log(keyName + " : " + value);
}
}
}
}
}
}
}