-
Notifications
You must be signed in to change notification settings - Fork 24
UnhandledPromiseRejection thrown from within SDK #41
Copy link
Copy link
Closed
Description
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);
});Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels