debuggability.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. "use strict";
  2. module.exports = function(Promise, CapturedTrace) {
  3. var async = require("./async.js");
  4. var Warning = require("./errors.js").Warning;
  5. var util = require("./util.js");
  6. var canAttachTrace = util.canAttachTrace;
  7. var unhandledRejectionHandled;
  8. var possiblyUnhandledRejection;
  9. var debugging = false || (util.isNode &&
  10. (!!process.env["BLUEBIRD_DEBUG"] ||
  11. process.env["NODE_ENV"] === "development"));
  12. if (debugging) {
  13. async.disableTrampolineIfNecessary();
  14. }
  15. Promise.prototype._ensurePossibleRejectionHandled = function () {
  16. this._setRejectionIsUnhandled();
  17. async.invokeLater(this._notifyUnhandledRejection, this, undefined);
  18. };
  19. Promise.prototype._notifyUnhandledRejectionIsHandled = function () {
  20. CapturedTrace.fireRejectionEvent("rejectionHandled",
  21. unhandledRejectionHandled, undefined, this);
  22. };
  23. Promise.prototype._notifyUnhandledRejection = function () {
  24. if (this._isRejectionUnhandled()) {
  25. var reason = this._getCarriedStackTrace() || this._settledValue;
  26. this._setUnhandledRejectionIsNotified();
  27. CapturedTrace.fireRejectionEvent("unhandledRejection",
  28. possiblyUnhandledRejection, reason, this);
  29. }
  30. };
  31. Promise.prototype._setUnhandledRejectionIsNotified = function () {
  32. this._bitField = this._bitField | 524288;
  33. };
  34. Promise.prototype._unsetUnhandledRejectionIsNotified = function () {
  35. this._bitField = this._bitField & (~524288);
  36. };
  37. Promise.prototype._isUnhandledRejectionNotified = function () {
  38. return (this._bitField & 524288) > 0;
  39. };
  40. Promise.prototype._setRejectionIsUnhandled = function () {
  41. this._bitField = this._bitField | 2097152;
  42. };
  43. Promise.prototype._unsetRejectionIsUnhandled = function () {
  44. this._bitField = this._bitField & (~2097152);
  45. if (this._isUnhandledRejectionNotified()) {
  46. this._unsetUnhandledRejectionIsNotified();
  47. this._notifyUnhandledRejectionIsHandled();
  48. }
  49. };
  50. Promise.prototype._isRejectionUnhandled = function () {
  51. return (this._bitField & 2097152) > 0;
  52. };
  53. Promise.prototype._setCarriedStackTrace = function (capturedTrace) {
  54. this._bitField = this._bitField | 1048576;
  55. this._fulfillmentHandler0 = capturedTrace;
  56. };
  57. Promise.prototype._isCarryingStackTrace = function () {
  58. return (this._bitField & 1048576) > 0;
  59. };
  60. Promise.prototype._getCarriedStackTrace = function () {
  61. return this._isCarryingStackTrace()
  62. ? this._fulfillmentHandler0
  63. : undefined;
  64. };
  65. Promise.prototype._captureStackTrace = function () {
  66. if (debugging) {
  67. this._trace = new CapturedTrace(this._peekContext());
  68. }
  69. return this;
  70. };
  71. Promise.prototype._attachExtraTrace = function (error, ignoreSelf) {
  72. if (debugging && canAttachTrace(error)) {
  73. var trace = this._trace;
  74. if (trace !== undefined) {
  75. if (ignoreSelf) trace = trace._parent;
  76. }
  77. if (trace !== undefined) {
  78. trace.attachExtraTrace(error);
  79. } else if (!error.__stackCleaned__) {
  80. var parsed = CapturedTrace.parseStackAndMessage(error);
  81. util.notEnumerableProp(error, "stack",
  82. parsed.message + "\n" + parsed.stack.join("\n"));
  83. util.notEnumerableProp(error, "__stackCleaned__", true);
  84. }
  85. }
  86. };
  87. Promise.prototype._warn = function(message) {
  88. var warning = new Warning(message);
  89. var ctx = this._peekContext();
  90. if (ctx) {
  91. ctx.attachExtraTrace(warning);
  92. } else {
  93. var parsed = CapturedTrace.parseStackAndMessage(warning);
  94. warning.stack = parsed.message + "\n" + parsed.stack.join("\n");
  95. }
  96. CapturedTrace.formatAndLogError(warning, "");
  97. };
  98. Promise.onPossiblyUnhandledRejection = function (fn) {
  99. possiblyUnhandledRejection = typeof fn === "function" ? fn : undefined;
  100. };
  101. Promise.onUnhandledRejectionHandled = function (fn) {
  102. unhandledRejectionHandled = typeof fn === "function" ? fn : undefined;
  103. };
  104. Promise.longStackTraces = function () {
  105. if (async.haveItemsQueued() &&
  106. debugging === false
  107. ) {
  108. throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/DT1qyG\u000a");
  109. }
  110. debugging = CapturedTrace.isSupported();
  111. if (debugging) {
  112. async.disableTrampolineIfNecessary();
  113. }
  114. };
  115. Promise.hasLongStackTraces = function () {
  116. return debugging && CapturedTrace.isSupported();
  117. };
  118. if (!CapturedTrace.isSupported()) {
  119. Promise.longStackTraces = function(){};
  120. debugging = false;
  121. }
  122. return function() {
  123. return debugging;
  124. };
  125. };