Skip to content

UnhandledPromiseRejection thrown from within SDK #41

@viglucci

Description

@viglucci

Greetings,

It appears that the SDK has the potential to cause an UnhandledPromiseRejection when the Contentstack REST API returns a non-well-formed JSON response (such as HTML).

In the future versions of Node.js, this will cause the process to crash, as suggested by the deprecation warning:

[DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Exception Example

$ node index.js
(node:26048) UnhandledPromiseRejectionWarning: FetchError: invalid json response body at https://REDACTED:443/v3/content_types/REDACTED/entries/?locale=en-us&include_count=true&environment=REDACTED reason: Unexpected token < in JSON at position 9
    at eval (webpack://Contentstack/./node_modules/node-fetch/lib/index.mjs?:276:32)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:26048) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:26048) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Minimal reproduction example

npm install dotenv node-request-interceptor contentstack
require('dotenv').config()

const Contentstack = require('contentstack');
const { RequestInterceptor } = require('node-request-interceptor');
const { default: withDefaultInterceptors } = require('node-request-interceptor/lib/presets/default');

const interceptor = new RequestInterceptor(withDefaultInterceptors)

// Log any outgoing requests to contentstack and return a mock HTML response
// which will cause the SDK to throw an unhandled exception
interceptor.use((req) => {

    console.log('%s %s', req.method, req.url.href);

    return {
        status: 401,
        headers: {
            'x-powered-by': 'node-request-interceptor',
            'content-type': 'text/html'
        },
        body: `
        <html>
        <head></head>
        <body>
            <h1>Unauthorized</h1>
        </body>
        </html>
        `,
    }
});

const Stack = Contentstack.Stack(
    process.env.CONTENTSTACK_API_KEY,
    process.env.CONTENTSTACK_DELIVERY_TOKEN,
    process.env.CONTENTSTACK_ENVIRONMENT,
    process.env.CONTENTSTACK_DB_REGION || null,
    { timeout: 5000 });

Stack.setHost(process.env.CONTENTSTACK_HOST);

const Query = Stack
    .ContentType(process.env.CONTENTSTACK_CONTENT_TYPE)
    .Query({})
    .language("en-us")
    .includeCount();

// Executing this async invocation cause an unhandled promise rejection
Query
    .toJSON()
    .find()
    .then((res) => {
        const [,count] = res;
        console.log(`${count} total blogs.`);
    }, function (err) {
        // Error is not caught
        console.error(err);
    })
    .catch((err) => {
        // Error is not caught
        console.error(err);
    });

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions