Skip to content

CORS error is not handled properly #151

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 {}
    }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working.low priorityLow priority issues to be done eventually.t-toolingIssues with this label are in the ownership of the tooling team.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions