Skip to content

CORS error is not handled properly #151

Open
@mtrunkat

Description

@mtrunkat

I have a simple jest test that uses Apify client:

const { getApifyClient } = require('./helper');

const ACTOR = {
    name: `my-name`,
    versions: [
        {
            versionNumber: '0.1',
            envVars: [],
            sourceType: 'SOURCE_CODE',
            baseDockerImage: 'apify/actor-node-basic',
            sourceCode: '...',
        },
    ],
};

describe('test', () => {
    it('case', async () => {
        console.log(await getApifyClient().actors().create(ACTOR));
    });
});

Which fails with the following error

    Expected response object with a "data" property, but received: undefined

      18 | describe('test', () => {
      19 |     it('case', async () => {
    > 20 |         console.log(await client.actors().create(ACTOR));
         |                     ^
      21 |     });
      22 | });
      23 | 

      at pluckData (node_modules/apify-client/src/utils.js:21:11)
      at ActorCollectionClient._create (node_modules/apify-client/src/base/resource_collection_client.js:39:32)
      at Object.<anonymous> (src/test.js:20:21)

After doing some experiments I found out that it works when the test is executed in a Node environment with

--testEnvironment=node

So I updated test to simply do an Axios request as Axios is used in the client

const axios = require('axios');

describe('test', () => {
    it('case', async () => {
        console.log(await axios('http://example.com'));
    });
});

and it returned a following error

   Network Error

      at createError (node_modules/axios/lib/core/createError.js:16:15)
      at XMLHttpRequest.handleError (node_modules/axios/lib/adapters/xhr.js:83:14)
      at XMLHttpRequest.<anonymous> (node_modules/jsdom/lib/jsdom/living/helpers/create-event-accessor.js:32:32)
      at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:318:25)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
     ...

  console.error
    Error: Cross origin http://localhost forbidden
        at dispatchError (/Users/marek/Workspace/apify-status-page/node_modules/jsdom/lib/jsdom/living/xhr/xhr-utils.js:62:19)
        at Object.validCORSHeaders (/Users/marek/Workspace/apify-status-page/node_modules/jsdom/lib/jsdom/living/xhr/xhr-utils.js:74:5)
        at receiveResponse (/Users/marek/Workspace/apify-status-page/node_modules/jsdom/lib/jsdom/living/xhr/XMLHttpRequest-impl.js:796:19)
        ...

which is not probably handled properly in Apify Client. The problem happens here https://github.com/apify/apify-client-js/blob/master/src/http_client.js#L116 where the response has an empty body but doesn't contain an error so it gets returned:

    {
      data: undefined,
      status: 201,
      statusText: 'Created',
      headers: {
        'content-type': 'application/json; charset=utf-8',
        'cache-control': 'no-cache, no-store, must-revalidate',
        pragma: 'no-cache',
        expires: '0'
      },
      config: {
        url: 'https://api.apify.com/v2/acts',
        method: 'post',
        data: '{"name":"my-name-5","versions":[{"versionNumber":"0.1","envVars":[],"sourceType":"SOURCE_CODE","baseDockerImage":"apify/actor-node-basic","sourceCode":"..."}]}',
        headers: {
          'User-Agent': 'ApifyClient/1.0.1 (Darwin; Node/v12.14.1); isAtHome/false',
          'Content-Type': 'application/json;charset=utf-8'
        },
        params: { token: 'xxxx' },
        transformRequest: null,
        transformResponse: null,
        paramsSerializer: [Function: paramsSerializer],
        timeout: 360000,
        adapter: [Function: xhrAdapter],
        responseType: 'arraybuffer',
        xsrfCookieName: 'XSRF-TOKEN',
        xsrfHeaderName: 'X-XSRF-TOKEN',
        maxContentLength: -1,
        maxBodyLength: -1,
        httpAgent: Agent {
          _events: [Object: null prototype],
          _eventsCount: 1,
          _maxListeners: undefined,
          defaultPort: 80,
          protocol: 'http:',
          options: [Object],
          requests: {},
          sockets: {},
          freeSockets: {},
          keepAliveMsecs: 1000,
          keepAlive: true,
          maxSockets: Infinity,
          maxFreeSockets: 256,
          createSocketCount: 0,
          createSocketCountLastCheck: 0,
          createSocketErrorCount: 0,
          createSocketErrorCountLastCheck: 0,
          closeSocketCount: 0,
          closeSocketCountLastCheck: 0,
          errorSocketCount: 0,
          errorSocketCountLastCheck: 0,
          requestCount: 0,
          requestCountLastCheck: 0,
          timeoutSocketCount: 0,
          timeoutSocketCountLastCheck: 0,
          [Symbol(agentkeepalive#currentId)]: 0
        },
        httpsAgent: HttpsAgent {
          _events: [Object: null prototype],
          _eventsCount: 1,
          _maxListeners: undefined,
          defaultPort: 443,
          protocol: 'https:',
          options: [Object],
          requests: {},
          sockets: {},
          freeSockets: {},
          keepAliveMsecs: 1000,
          keepAlive: true,
          maxSockets: Infinity,
          maxFreeSockets: 256,
          createSocketCount: 0,
          createSocketCountLastCheck: 0,
          createSocketErrorCount: 0,
          createSocketErrorCountLastCheck: 0,
          closeSocketCount: 0,
          closeSocketCountLastCheck: 0,
          errorSocketCount: 0,
          errorSocketCountLastCheck: 0,
          requestCount: 0,
          requestCountLastCheck: 0,
          timeoutSocketCount: 0,
          timeoutSocketCountLastCheck: 0,
          maxCachedSessions: 100,
          _sessionCache: [Object],
          [Symbol(agentkeepalive#currentId)]: 0
        },
        validateStatus: null
      },
      request: XMLHttpRequest {}
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working.low priorityLow priority issues to be done eventually.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions