Intermittent - Invalid JSON RPC response: ""

Summary: I have storage contracts that have 100s of records in them. I loop through the records and fetch each record one by one from the contract and build a list. Every so often with larger tables I get an error from web3js/infura rinkeby

Invalid JSON RPC response: “”.

Background: I’m using web3js w/ http infura rinkeby endpoint to send the requests, I’m on the free tier as well. The errors are cascading, if I get an error trying to fetch record number 30, it will throw errors for the rest of the table records.

I’m wondering if how I create my web3 object is causing an issue? I’m create a new web3 object before each request to infura. I’m not sure if creating a new object creates a persistent connection and I’m getting errors because I have too many open.

@dillonfromatra, can you share your code with us and the full error response?

var Web3 = require('web3');
const { GetEthereumNodeUrl } = require('../../eth');
const { GetRecordsLength } = require('./get-records-length');

const GetRecordFromContract = (table, index, network) => {
  return new Promise(function(resolve, reject){
    try {
      const ethereumUrl = GetEthereumNodeUrl(network);
      const web3 = new Web3(ethereumUrl);
      let contract = new web3.eth.Contract(JSON.parse(table.abi), table[network]);
      contract.methods.GetByIndex(index).call().then((res)=>{
        resolve(res);
      },(err)=>{
        console.log('GetRecordFromContract',err);
        console.log('table input', table);
        console.log('network input', network);
        console.log('index input', index);
        reject(err);
      });
    }catch(err){
      console.log('GetRecordFromContract',err);
      console.log('table input', table);
      console.log('network input', network);
      console.log('index input', index);
      reject(err);
    }
  });
}

const GetInsertRecordEvents = ({
  table,
  network,
  recordIds
}) => {
  return new Promise((resolve, reject) => {
    try {

      const ethereumUrl = GetEthereumNodeUrl(network);
      const web3 = new Web3(ethereumUrl);
      let contract = new web3.eth.Contract(JSON.parse(table.abi), table[network]);

      contract.getPastEvents('Inserted', {
          filter: { _recordId: recordIds },
          fromBlock: 0,
          toBlock: 'latest'
      },(error, events) => {

        if(error){
          console.log('getPastEvents Error', error);
          reject(error);
        }else{
          resolve({
            events
          });
        }

      })

    }catch(err){
      console.log('GetRecordsEventInfo Error', err);
      reject(err)
    }
  })
}

const GetAllRecordsFromContract = (table, network, txinfo) =>{
  return new Promise(async (resolve, reject)=>{
    try{
      const length = await GetRecordsLength(table, network);
      let recordPromises = [];
      for(let x = 0; x < length; x++){
        recordPromises.push(GetRecordFromContract(table, x, network))
      }
      Promise.all(recordPromises).then(async (records)=>{
        if(txinfo){

          const recordIds = records.map(r => r.recordId);
          const { events } = await GetInsertRecordEvents({
            table,
            network,
            recordIds
          });

          records = records.map(record=>{
            //find event
            const event = events.find(e => e.returnValues._recordId === record.recordId);
            return {...record, event};
          })

          resolve(records);

        }else{
          resolve(records);
        }
      });
    }catch(err){
      console.log('GetAllRecordsFromContract',err);
      console.log('table input', table);
      console.log('network input', network);
      reject(err);
    }
  });
}

module.exports = {
  GetRecordFromContract,
  GetAllRecordsFromContract
}

Error

GetRecordFromContract Error: Invalid JSON RPC response: “”
at Object.InvalidResponse (/opt/node_modules/web3/node_modules/web3-core-helpers/src/errors.js:42:16)
at XMLHttpRequest.request.onreadystatechange (/opt/node_modules/web3/node_modules/web3-providers-http/src/index.js:87:32)
at XMLHttpRequestEventTarget.dispatchEvent (/opt/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
at XMLHttpRequest._setReadyState (/opt/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
at XMLHttpRequest._onHttpRequestError (/opt/node_modules/xhr2-cookies/dist/xml-http-request.js:349:14)
at ClientRequest. (/opt/node_modules/xhr2-cookies/dist/xml-http-request.js:252:61)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at TLSSocket.socketErrorListener (_http_client.js:355:9)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickDomainCallback (internal/process/next_tick.js:218:9)

Log

table input { columns:
[ { name: ‘dApp’, type: ‘text’, solType: ‘string’ },
{ name: ‘Description’, type: ‘text’, solType: ‘string’ },
{ name: ‘URL’, type: ‘text’, solType: ‘string’ },
{ name: ‘Votes’, type: ‘number’, solType: ‘uint’ },
{ name: ‘Created’, type: ‘date’, solType: ‘uint’ },
{ name: ‘Owner’, type: ‘address’, solType: ‘address’ } ],
rinkeby: ‘0x1039D595501b22a5F03886F7AE4FE354dde3558E’,
abi: ‘[{“constant”:true,“inputs”:[{“name”:“recordId”,“type”:“address”}],“name”:“GetById”,“outputs”:[{“name”:“index”,“type”:“uint256”},{“components”:[{“name”:“A_dApp”,“type”:“string”},{“name”:“A_Description”,“type”:“string”},{“name”:“A_URL”,“type”:“string”},{“name”:“A_Votes”,“type”:“uint256”},{“name”:“A_Created”,“type”:“uint256”},{“name”:“A_Owner”,“type”:“address”}],“name”:“record”,“type”:“tuple”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“GetLength”,“outputs”:[{“name”:“count”,“type”:“uint256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:“recordId”,“type”:“address”},{“components”:[{“name”:“A_dApp”,“type”:“string”},{“name”:“A_Description”,“type”:“string”},{“name”:“A_URL”,“type”:“string”},{“name”:“A_Votes”,“type”:“uint256”},{“name”:“A_Created”,“type”:“uint256”},{“name”:“A_Owner”,“type”:“address”}],“name”:“recordData”,“type”:“tuple”}],“name”:“Update”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:false,“inputs”:[],“name”:“AcceptOwnership”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:"",“type”:“address”}],“name”:“Table”,“outputs”:[{“components”:[{“name”:“A_dApp”,“type”:“string”},{“name”:“A_Description”,“type”:“string”},{“name”:“A_URL”,“type”:“string”},{“name”:“A_Votes”,“type”:“uint256”},{“name”:“A_Created”,“type”:“uint256”},{“name”:“A_Owner”,“type”:“address”}],“name”:“data”,“type”:“tuple”},{“name”:“idListPointer”,“type”:“uint256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:“recordIndex”,“type”:“uint256”}],“name”:“GetByIndex”,“outputs”:[{“name”:“recordId”,“type”:“address”},{“components”:[{“name”:“A_dApp”,“type”:“string”},{“name”:“A_Description”,“type”:“string”},{“name”:“A_URL”,“type”:“string”},{“name”:“A_Votes”,“type”:“uint256”},{“name”:“A_Created”,“type”:“uint256”},{“name”:“A_Owner”,“type”:“address”}],“name”:“record”,“type”:“tuple”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“Name”,“outputs”:[{“name”:"",“type”:“string”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“owner”,“outputs”:[{“name”:"",“type”:“address”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“GetPermissionListLength”,“outputs”:[{“name”:“length”,“type”:“uint256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“components”:[{“name”:“A_dApp”,“type”:“string”},{“name”:“A_Description”,“type”:“string”},{“name”:“A_URL”,“type”:“string”},{“name”:“A_Votes”,“type”:“uint256”},{“name”:“A_Created”,“type”:“uint256”},{“name”:“A_Owner”,“type”:“address”}],“name”:“recordData”,“type”:“tuple”}],“name”:“Insert”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:"",“type”:“uint256”}],“name”:“IdList”,“outputs”:[{“name”:"",“type”:“address”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:“recordId”,“type”:“address”}],“name”:“Exists”,“outputs”:[{“name”:“exists”,“type”:“bool”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_newOwner",“type”:“address”}],“name”:“TransferOwnership”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:“recordId”,“type”:“address”}],“name”:“Delete”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:“index”,“type”:“uint256”}],“name”:“GetPermission”,“outputs”:[{“name”:“permissionAddress”,“type”:“address”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“newOwner”,“outputs”:[{“name”:"",“type”:“address”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:“addr”,“type”:“address”}],“name”:“AddPermission”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:"",“type”:“uint256”}],“name”:“permissionedList”,“outputs”:[{“name”:"",“type”:“address”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:“sender”,“type”:“address”}],“name”:“HasPermission”,“outputs”:[{“name”:“permission”,“type”:“bool”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:“addr”,“type”:“address”}],“name”:“RemovePermission”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“anonymous”:false,“inputs”:[{“indexed”:false,“name”:"_sender",“type”:“address”},{“indexed”:false,“name”:"_recordId",“type”:“address”}],“name”:“Inserted”,“type”:“event”},{“anonymous”:false,“inputs”:[{“indexed”:false,“name”:"_sender",“type”:“address”},{“indexed”:false,“name”:"_recordId",“type”:“address”}],“name”:“Updated”,“type”:“event”},{“anonymous”:false,“inputs”:[{“indexed”:false,“name”:"_sender",“type”:“address”},{“indexed”:false,“name”:"_recordId",“type”:“address”}],“name”:“Deleted”,“type”:“event”},{“anonymous”:false,“inputs”:[{“indexed”:false,“name”:"_from",“type”:“address”},{“indexed”:false,“name”:"_to",“type”:“address”}],“name”:“OwnershipTransferred”,“type”:“event”},{“anonymous”:false,“inputs”:[{“indexed”:false,“name”:"_address",“type”:“address”}],“name”:“PermissionAdded”,“type”:“event”},{“anonymous”:false,“inputs”:[{“indexed”:false,“name”:"_address",“type”:“address”}],“name”:“PermissionRevoked”,“type”:“event”}]’,
status: ‘Live’,
created: 1559197751839,
id: ‘88dc132c-a104-4fed-984a-7e23feeec7fb’,
description: ‘A list of dApps created on Atra by users’,
name: ‘Atraverse’,
transactionHash: ‘0xd56ea0372c5ec3f188b8271724bf8c1c4736727148086620f51c721bcd3a2bc6’ }

network input rinkeby

2019-11-12T19:39:37.779Z d1a46dd1-a0f7-414c-a332-fabf387b3199 index input 31

This looks like an eth_call request might be timing out or potentially getting an HTTP error. I tried running this code snippet locally but was not able to reproduce. Could you please add some logging to show the http response code and response body you are getting?

I’m not sure how to do that I log the error in catch/reject block of the call promise, is there another place I can log? @egalano

Any updates on how to log the http res from web3 and infura so we can resolve this issue?