Skip to content

Commit fb18bb2

Browse files
authored
Fix/unhandled promise rejection call api (#481)
* Add an additional option to disable promises in call_api -- disable_promises:bool
1 parent f5c6809 commit fb18bb2

File tree

4 files changed

+100
-12
lines changed

4 files changed

+100
-12
lines changed

lib-es5/uploader.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ function call_api(action, callback, options, get_params) {
471471
callback = function callback() {};
472472
}
473473

474+
var USE_PROMISES = !options.disable_promises;
475+
474476
var deferred = Q.defer();
475477
if (options == null) {
476478
options = {};
@@ -494,7 +496,10 @@ function call_api(action, callback, options, get_params) {
494496
// Already reported
495497
} else if (res.error) {
496498
errorRaised = true;
497-
deferred.reject(res);
499+
500+
if (USE_PROMISES) {
501+
deferred.reject(res);
502+
}
498503
callback(res);
499504
} else if (includes([200, 400, 401, 404, 420, 500], res.statusCode)) {
500505
var buffer = "";
@@ -510,16 +515,22 @@ function call_api(action, callback, options, get_params) {
510515
result = parseResult(buffer, res);
511516
if (result.error) {
512517
result.error.http_code = res.statusCode;
513-
deferred.reject(result.error);
518+
if (USE_PROMISES) {
519+
deferred.reject(result.error);
520+
}
514521
} else {
515522
cacheResults(result, options);
516-
deferred.resolve(result);
523+
if (USE_PROMISES) {
524+
deferred.resolve(result);
525+
}
517526
}
518527
callback(result);
519528
});
520529
res.on("error", function (error) {
521530
errorRaised = true;
522-
deferred.reject(error);
531+
if (USE_PROMISES) {
532+
deferred.reject(error);
533+
}
523534
callback({ error });
524535
});
525536
} else {
@@ -528,7 +539,9 @@ function call_api(action, callback, options, get_params) {
528539
http_code: res.statusCode,
529540
name: "UnexpectedResponse"
530541
};
531-
deferred.reject(error);
542+
if (USE_PROMISES) {
543+
deferred.reject(error);
544+
}
532545
callback({ error });
533546
}
534547
};
@@ -550,7 +563,10 @@ function call_api(action, callback, options, get_params) {
550563
if (isObject(result)) {
551564
return result;
552565
}
553-
return deferred.promise;
566+
567+
if (USE_PROMISES) {
568+
return deferred.promise;
569+
}
554570
}
555571

556572
function post(url, post_data, boundary, file, callback, options) {

lib/uploader.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,8 @@ function call_api(action, callback, options, get_params) {
386386
callback = function () {};
387387
}
388388

389+
const USE_PROMISES = !options.disable_promises;
390+
389391
let deferred = Q.defer();
390392
if (options == null) {
391393
options = {};
@@ -403,7 +405,10 @@ function call_api(action, callback, options, get_params) {
403405
// Already reported
404406
} else if (res.error) {
405407
errorRaised = true;
406-
deferred.reject(res);
408+
409+
if (USE_PROMISES) {
410+
deferred.reject(res);
411+
}
407412
callback(res);
408413
} else if (includes([200, 400, 401, 404, 420, 500], res.statusCode)) {
409414
let buffer = "";
@@ -419,16 +424,22 @@ function call_api(action, callback, options, get_params) {
419424
result = parseResult(buffer, res);
420425
if (result.error) {
421426
result.error.http_code = res.statusCode;
422-
deferred.reject(result.error);
427+
if (USE_PROMISES) {
428+
deferred.reject(result.error);
429+
}
423430
} else {
424431
cacheResults(result, options);
425-
deferred.resolve(result);
432+
if (USE_PROMISES) {
433+
deferred.resolve(result);
434+
}
426435
}
427436
callback(result);
428437
});
429438
res.on("error", (error) => {
430439
errorRaised = true;
431-
deferred.reject(error);
440+
if (USE_PROMISES) {
441+
deferred.reject(error);
442+
}
432443
callback({ error });
433444
});
434445
} else {
@@ -437,7 +448,9 @@ function call_api(action, callback, options, get_params) {
437448
http_code: res.statusCode,
438449
name: "UnexpectedResponse"
439450
};
440-
deferred.reject(error);
451+
if (USE_PROMISES) {
452+
deferred.reject(error);
453+
}
441454
callback({ error });
442455
}
443456
};
@@ -451,7 +464,10 @@ function call_api(action, callback, options, get_params) {
451464
if (isObject(result)) {
452465
return result;
453466
}
454-
return deferred.promise;
467+
468+
if (USE_PROMISES) {
469+
return deferred.promise;
470+
}
455471
}
456472

457473
function post(url, post_data, boundary, file, callback, options) {

test/integration/api/uploader/uploader_spec.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,61 @@ describe("uploader", function () {
794794
});
795795
});
796796

797+
it("should reject with promise rejection if disable_promises: false", function (done) {
798+
const spy = sinon.spy();
799+
800+
cloudinary.v2.uploader.upload_large(EMPTY_IMAGE, { disable_promises: false }, () => {});
801+
802+
function unhandledRejection() {
803+
spy();
804+
}
805+
process.on('unhandledRejection', unhandledRejection);
806+
807+
// Promises are not disabled meaning we should throw unhandledRejection
808+
setTimeout(() => {
809+
expect(sinon.assert.called(spy));
810+
process.removeListener('unhandledRejection', unhandledRejection);
811+
done();
812+
}, 2000);
813+
});
814+
815+
it("should reject with promise rejection by default", function (done) {
816+
const spy = sinon.spy();
817+
818+
cloudinary.v2.uploader.upload_large(EMPTY_IMAGE, () => {});
819+
820+
function unhandledRejection() {
821+
spy();
822+
}
823+
process.on('unhandledRejection', unhandledRejection);
824+
825+
// Promises are not disabled meaning we should throw unhandledRejection
826+
setTimeout(() => {
827+
expect(sinon.assert.called(spy));
828+
process.removeListener('unhandledRejection', unhandledRejection);
829+
done();
830+
}, 2000);
831+
});
832+
833+
it("should reject without promise rejection if disable_promises: true", function (done) {
834+
const spy = sinon.spy();
835+
836+
cloudinary.v2.uploader.upload_large(EMPTY_IMAGE, { disable_promises: true }, () => {});
837+
838+
function unhandledRejection() {
839+
spy();
840+
}
841+
process.on('unhandledRejection', unhandledRejection);
842+
843+
// Promises are disabled meaning unhandledRejection was not called
844+
setTimeout(() => {
845+
expect(sinon.assert.notCalled(spy));
846+
process.removeListener('unhandledRejection', unhandledRejection);
847+
done();
848+
}, 2000);
849+
});
850+
851+
797852
it("should reject promise if error code is returned from the server", function () {
798853
return cloudinary.v2.uploader.upload(EMPTY_IMAGE, {
799854
tags: UPLOAD_TAGS

types/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ declare module 'cloudinary' {
508508
upload_preset?: string;
509509
use_filename?: boolean;
510510
chunk_size?: number;
511+
disable_promises?: boolean;
511512

512513
[futureKey: string]: any;
513514
}

0 commit comments

Comments
 (0)