APIs & Integrations

cyberjack
Member

This is not peano's fault.

I've been developing an app to provide better reporting for my company using Google Sheets and Appscripts. The MVP is working out pretty well so far.

 

I'm trying to add some capabilities in regards to contact web conversion activities and have been using CRM V3 to get all relevant contact properties and in the process ran into a rather humorous error message. I couldn't find any references on Google so I guess I'm lucky?

 

"Exception: Request failed for https://api.hubapi.com returned code 400. Truncated server response: {"status":"error","message":"Exception while calling underlying service. This is not peano's fault."

 

I think this has to do with paging beyond 10,000 in CRM V3 but I'm not sure. Any thoughts? 

 

9 Replies 9
mercadoradar
Participant

This is not peano's fault.

I'm getting the same error:

 

{"status":"error","message":"Exception while calling underlying service. This is not peano's fault.","correlationId":"b9a67789-16b5-4406-a40b-cd7295a1ee3e","category":"VALIDATION_ERROR"}

I'm using the python API provided by hubspot and getting all contacts from hubspot.

 

This error doesn't make any sense, since sometimes it works and sometimes it doesn't, without changing any code.

 

I'm fixing this error by only stopping my server app and running it again, with the same code.

 

Could at least hubspot provide better error messages?

 

Thanks,

Rodrigo.

0 Upvotes
cyberjack
Member

This is not peano's fault.

Hey Rodrigo, looks like you win the peano bingo game as well 😉

 

Can you show a snippet of the code that is generating this error? 

0 Upvotes
mercadoradar
Participant

This is not peano's fault.

Hey cyberjack, 

 

Yeah, I think we are winning this bingo game lol

 

Sure, here it is:

 

 

from hubspot.crm.contacts.models.simple_public_object import SimplePublicObject

class Contact:

    def list(self):
        properties = ['email', 'firstname', 'lastname', 'external_contact_id', 'external_account_id', 'city', 'state',
                      'country', 'phone']
        insert_data = []
        active_responses = self.hubspot.crm.contacts.get_all(properties=properties)
        archived_responses = self.hubspot.crm.contacts.get_all(properties=properties, archived=True)
        insert_data.extend(self.__parse_response(active_responses))
        insert_data.extend(self.__parse_response(archived_responses))
        return insert_data

 

I hope we have some response from Hubspot team soon

0 Upvotes
WendyGoh
HubSpot Employee
HubSpot Employee

This is not peano's fault.

Hey @mercadoradar @cyberjack,

 

Thanks for bringing this up! 

 

For context, the peano's fault error could be due to anything.  In this case, I have reached out to our internal team and we are looking to unwrap peano errors so that it returns a standard and meaningful error mesages. 

0 Upvotes
cyberjack
Member

This is not peano's fault.

No worries, this has been a ton of fun! I suspect the error message is an easter egg planted by one of your more senior programmers as I am guessing it relates to Giuseppe Peano, a famous mathematician from the 19th century. 

 

This is above my paygrade but from what I understand, Peono is sort of the Pythagoras of natural numbers. The axiomatization of natural numbers looks a lot like the precursors to an iterator. While I can't speak for Rodrigo, I suspect my error came about because I ran into the API query limit of 10,000. 

 

Thanks again Wendy, and looking forward to hearing Peono's story. 

0 Upvotes
WendyGoh
HubSpot Employee
HubSpot Employee

This is not peano's fault.

Hey @cyberjack,

 

This is an interesting one! In order for me to troubleshoot further into this, could you share with me the following:

 

1. What's the exact endpoint that you're using?

2. The POST body (if any)

3. Snippet of the code implementation

0 Upvotes
cyberjack
Member

This is not peano's fault.

This is the exact error code: 

Exception: Request failed for https://api.hubapi.com returned code 400. Truncated server response: {"status":"error","message":"Exception while calling underlying service. This is not peano's fault.","correlationId":"6c666214-ee88-42b7-94c6-ff1a0... (use muteHttpExceptions option to examine full response) at getConversions(Code:491:32)

 

I don't have the original code that generated that error because I have moved on to a different strategy. Rather than trolling through all 22k contacts, I'm using CRM V3 Search function so now I have a new problem lol. Whereas before I was using the GET method, search uses the POST method which I am less familiar with when it comes to AppScripts. 

 

I am able to get a response via Postman but not in Appscripts. The error I get now is "Authentication credentials not found." which makes me think that my token is not being passed into the query parameter. Here's the code:

 

function getConversions() {

  // Prepare authentication to Hubspot
  var service = getService();
  var headers = {headers: {'Authorization': 'Bearer ' + service.getAccessToken()}};
  Logger.log(headers);
    

var raw = JSON.stringify({"filterGroups":[{"filters":[{"propertyName":"hs_analytics_last_visit_timestamp","operator":"GT","value":"1561514165666"}]}],"limit":100,"after":0});  
  
var options = {
  'method' : 'post',
  headers: headers,
  'contentType': 'application/json',
  // Convert the JavaScript object to a JSON string.
  body : raw,
  redirect: 'follow',
  "muteHttpExceptions": true
};
var response = UrlFetchApp.fetch('https://api.hubapi.com/crm/v3/objects/contacts/search?', options);
var result = JSON.parse(response.getContentText());
    Logger.log(result);

 
};
  

 

0 Upvotes
WendyGoh
HubSpot Employee
HubSpot Employee

This is not peano's fault.

Hey @cyberjack,

 

Could you try changing the header from 

 

  'contentType': 'application/json',

to

  Content-Type: 'application/json'

and see if it works? 

 

Referencing this post.

0 Upvotes
cyberjack
Member

This is not peano's fault.

Hey Wendy, sorry for the late response, I've been swamped with other work items but I managed to finally solve this confounding problem, I'll be it through trial and error. 

 

I used the link that you sent and started examining JSON object that was being sent to the Hubspot API and indeed there are mutations that happen between what is written in Google App Scripts GAS and the end product. 

 

As an example, GAS has the UrlFetchApp as a Class vs Javascript Fetch and has some material differences like it doesn't have body or redirect as properties. Instead, you have to use payload which is mutated once it is sent. In the same vein, you were onto something when you tried to correct for the content type syntax. 

 

With your help, Tanaike from stack overflow, and a lot of hours the solution included the syntactical changes to the JSON payload as well as changing the authorization to the API key which is how the search query is demonstrated on Hubspot's new developer portal. Reading is winning? In the end, the solution may not be pretty but it works. 

 

// array of people with activities
var activePeople = Array();
var keep_going = true;
var offset=0;

//a loop that runs through the api response, it also updates the pagination for repeat queries
while(keep_going){
//Search query
var raw = {"filterGroups":[{"filters":[{"propertyName":"hs_analytics_last_timestamp","operator":"GT","value":"1561514165666"}]}],"properties":["hs_analytics_num_visits","firstname","lastname","company"],"limit":100,"after":offset}
//Logger.log(raw.after);
//JSON POST Data sent to Hubspot server
var options = {
method : 'post',
contentType: "application/json",
// Convert the JavaScript object to a JSON string.
payload : JSON.stringify(raw),
muteHttpExceptions: true
};

// Uses CRM V3's search capability using the API vs Token. Token approach did not work
var url = API_URL + "/crm/v3/objects/contacts/search?hapikey=mykey";
var response = UrlFetchApp.fetch(url, options);
var result = JSON.parse(response.getContentText());
const pagination=(Math.floor(result.total/100)*100);

keep_going=JSON.stringify(result.paging);

//Logger.log(keep_going);
//if(keep_going){Logger.log("thisfired")}else{Logger.log("this never fired")};


Logger.log(offset);
Logger.log(options)



// For each deal, we take the stageId, source & amount
result.results.forEach(function(person) {
var firstName = (person.properties.hasOwnProperty("firstname")) ? person.properties.firstname : "unknown";
var lastName = (person.properties.hasOwnProperty("lastname")) ? person.properties.lastname : "unknown";
var countViews = (person.properties.hasOwnProperty("hs_analytics_num_visits")) ? person.properties.hs_analytics_num_visits : "unknown";
var company = (person.properties.hasOwnProperty("company")) ? person.properties.company : "unknown";


activePeople.push([firstName, lastName, countViews,company]);


});

if(keep_going){offset=result.paging.next.after;}else{Logger.log(activePeople.length)};


}

0 Upvotes