Skip to main content

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
    -RecordActionWrapper

  • Getting Record Count for a specific Tag operation
    -CountWrapper

  • Operations involving BaseCurrency
    -BaseCurrencyActionWrapper

  • Lead convert operation
    -ConvertActionWrapper

  • Retrieving Deleted records operation:
    -DeletedRecordsWrapper

  • Record image download operation
    -FileBodyWrapper

  • MassUpdate 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);
                        }
                    }
                }
            }
        }
    }
}