FrodmanG
FrodmanG

Reputation: 672

Method: spreadsheets.values.append TypeError: Converting circular structure to JSON

I've been using the Google Sheets API successfully. I've managed to use the spreadsheets.values.update, and spreadsheets.values.get methods with no errors. Today I've been trying to use the method: spreadsheets.values.append. This method simply appends a row of data to the end of the table. In the developer portal, you can "try this api", and when I do I get a 200 response.

However, when I run exactly the same method (including parameters!) in my NodeJS/Express app I get the error:

"TypeError: Converting circular structure to JSON",

Yet, when I look at the Google Sheet, the data has successfully been appended. This is what my code looks like:

function postValid(req, res) {
    const data = req.body;
    console.log('received validate post');
    sheets.spreadsheets.values.append(  {
        auth: jwtClient,
        spreadsheetId: ssId,
        range: 'Valid!A:C',
        resource: {
            values: [
                [1, 2, 3]
            ]
        },
        valueInputOption: 'USER_ENTERED',
    }, (err, response) => {
        if (err) {
            res.status(500);
            res.send('The API returned an error: ' + err);
        }
        res.send(response)
    })
}

I could ignore the error, as the data does get sent, but I'd really like to know what is causing this circular structure error. How can I go about debugging this?

Like I said the get and update methods with almost the same structure works fine so it isn't the {auth: jwtClient, spreadsheetId: ssId, } parts, and the rest is pretty standard JSON. I just don't get it.

Has anyone run into the same problem?

UPDATE: I've narrowed down the issue. If I disable Express's JSON body parser, then I can view the full response. Here it is below, you'll see the circular reference is part of the Request, but this request is done via the googleapi methods, is this a possible bug with the googleapi library?

{ status: 200,
  statusText: 'OK',
  headers:
   { 'content-type': 'application/json; charset=UTF-8',
     vary: 'X-Origin, Referer, Origin,Accept-Encoding',
     date: 'Tue, 30 Oct 2018 12:22:09 GMT',
     server: 'ESF',
     'cache-control': 'private',
     'x-xss-protection': '1; mode=block',
     'x-frame-options': 'SAMEORIGIN',
     'alt-svc': 'quic=":443"; ma=2592000; v="44,43,39,35"',
     'accept-ranges': 'none',
     connection: 'close' },
  config:
   { adapter: [Function: httpAdapter],
     transformRequest: { '0': [Function: transformRequest] },
     transformResponse: { '0': [Function: transformResponse] },
     timeout: 0,
     xsrfCookieName: 'XSRF-TOKEN',
     xsrfHeaderName: 'X-XSRF-TOKEN',
     maxContentLength: 2147483648,
     validateStatus: [Function],
     headers:
      { Accept: 'application/json, text/plain, */*',
        'Content-Type': 'application/json;charset=utf-8',
        Authorization:
        <REMOVED>,
        'User-Agent': 'google-api-nodejs-client/1.6.1',
        'Content-Length': 29 },
     method: 'post',
     url:
      'https://sheets.googleapis.com/v4/spreadsheets/<REMOVED>/values/Valid!A:C:append',
     paramsSerializer: [Function],
     data: '{"values":[[null,null,null]]}',
     params: { valueInputOption: 'USER_ENTERED' } },
  request:
   ClientRequest {
     _events:
      { socket: [Function],
        abort: [Function],
        aborted: [Function],
        error: [Function],
        timeout: [Function],
        prefinish: [Function: requestOnPrefinish] },
     _eventsCount: 6,
     _maxListeners: undefined,
     output: [],
     outputEncodings: [],
     outputCallbacks: [],
     outputSize: 0,
     writable: true,
     _last: true,
     chunkedEncoding: false,
     shouldKeepAlive: false,
     useChunkedEncodingByDefault: true,
     sendDate: false,
     _removedConnection: false,
     _removedContLen: false,
     _removedTE: false,
     _contentLength: null,
     _hasBody: true,
     _trailer: '',
     finished: true,
     _headerSent: true,
     socket:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'sheets.googleapis.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'sheets.googleapis.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],   //<--HERE IS ONE ISSUE
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 78,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 575,
        [Symbol(kBytesWritten)]: 517,
        [Symbol(connect-options)]: [Object] },
     connection:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'sheets.googleapis.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'sheets.googleapis.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],  //<--Again another problem
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 78,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 575,
        [Symbol(kBytesWritten)]: 517,
        [Symbol(connect-options)]: [Object] },
     _header:
      'POST /v4/spreadsheets/<REMOVED>/values/Valid!A:C:append?valueInputOption=USER_ENTERED HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: application/json;charset=utf-8\r\nAuthorization: <REMOVED> User-Agent: google-api-nodejs-client/1.6.1\r\nContent-Length: 29\r\nHost: sheets.googleapis.com\r\nConnection: close\r\n\r\n',
     _onPendingData: [Function: noopPendingOutput],
     agent:
      Agent {
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        defaultPort: 443,
        protocol: 'https:',
        options: [Object],
        requests: {},
        sockets: [Object],
        freeSockets: {},
        keepAliveMsecs: 1000,
        keepAlive: false,
        maxSockets: Infinity,
        maxFreeSockets: 256,
        maxCachedSessions: 100,
        _sessionCache: [Object] },
     socketPath: undefined,
     timeout: undefined,
     method: 'POST',
     path:
      '/v4/spreadsheets/<REMOVED>/values/Valid!A:C:append?valueInputOption=USER_ENTERED',
     _ended: true,
     res:
      IncomingMessage {
        _readableState: [ReadableState],
        readable: false,
        _events: [Object],
        _eventsCount: 3,
        _maxListeners: undefined,
        socket: [TLSSocket],
        connection: [TLSSocket],
        httpVersionMajor: 1,
        httpVersionMinor: 1,
        httpVersion: '1.1',
        complete: true,
        headers: [Object],
        rawHeaders: [Array],
        trailers: {},
        rawTrailers: [],
        aborted: false,
        upgrade: false,
        url: '',
        method: null,
        statusCode: 200,
        statusMessage: 'OK',
        client: [TLSSocket],
        _consuming: true,
        _dumped: false,
        req: [Circular],  //<--Again another circular reference
        responseUrl:
         'https://sheets.googleapis.com/v4/spreadsheets/<REMOVED>/values/Valid!A:C:append?valueInputOption=USER_ENTERED',
        redirects: [] },
     aborted: undefined,
     timeoutCb: null,
     upgradeOrConnect: false,
     parser: null,
     maxHeadersCount: null,
     _redirectable:
      Writable {
        _writableState: [WritableState],
        writable: true,
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _options: [Object],
        _redirectCount: 0,
        _redirects: [],
        _requestBodyLength: 29,
        _requestBodyBuffers: [],
        _onNativeResponse: [Function],
        _currentRequest: [Circular],  //<-- Again!!
        _currentUrl:
         'https://sheets.googleapis.com/v4/spreadsheets/<REMOVED>/values/Valid!A:C:append?valueInputOption=USER_ENTERED' },
     [Symbol(isCorked)]: false,
     [Symbol(outHeadersKey)]:
      { accept: [Array],
        'content-type': [Array],
        authorization: [Array],
        'user-agent': [Array],
        'content-length': [Array],
        host: [Array] } },
  data:
   { spreadsheetId: <REMOVED>,
     tableRange: 'Valid!A1:C8',
     updates:
      { spreadsheetId: <REMOVED>,
        updatedRange: 'Valid!A9' } } }

Upvotes: 0

Views: 450

Answers (1)

Tamir Klein
Tamir Klein

Reputation: 3632

This is indeed coming from Google api response. I also seen it when calling other api such as https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query You have to make sure to call only the relevant part of the response and not attempt to convert it to JSON in order to avoid the circular error messags

Upvotes: 2

Related Questions