Blame view

node_modules/promise/src/rejection-tracking.js 2.93 KB
ce4c83ff   wxy   初始提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  'use strict';
  
  var Promise = require('./core');
  
  var DEFAULT_WHITELIST = [
    ReferenceError,
    TypeError,
    RangeError
  ];
  
  var enabled = false;
  exports.disable = disable;
  function disable() {
    enabled = false;
    Promise._onHandle = null;
    Promise._onReject = null;
  }
  
  exports.enable = enable;
  function enable(options) {
    options = options || {};
    if (enabled) disable();
    enabled = true;
    var id = 0;
    var displayId = 0;
    var rejections = {};
    Promise._onHandle = function (promise) {
      if (
        promise._state === 2 && // IS REJECTED
        rejections[promise._rejectionId]
      ) {
        if (rejections[promise._rejectionId].logged) {
          onHandled(promise._rejectionId);
        } else {
          clearTimeout(rejections[promise._rejectionId].timeout);
        }
        delete rejections[promise._rejectionId];
      }
    };
    Promise._onReject = function (promise, err) {
      if (promise._deferredState === 0) { // not yet handled
        promise._rejectionId = id++;
        rejections[promise._rejectionId] = {
          displayId: null,
          error: err,
          timeout: setTimeout(
            onUnhandled.bind(null, promise._rejectionId),
            // For reference errors and type errors, this almost always
            // means the programmer made a mistake, so log them after just
            // 100ms
            // otherwise, wait 2 seconds to see if they get handled
            matchWhitelist(err, DEFAULT_WHITELIST)
              ? 100
              : 2000
          ),
          logged: false
        };
      }
    };
    function onUnhandled(id) {
      if (
        options.allRejections ||
        matchWhitelist(
          rejections[id].error,
          options.whitelist || DEFAULT_WHITELIST
        )
      ) {
        rejections[id].displayId = displayId++;
        if (options.onUnhandled) {
          rejections[id].logged = true;
          options.onUnhandled(
            rejections[id].displayId,
            rejections[id].error
          );
        } else {
          rejections[id].logged = true;
          logError(
            rejections[id].displayId,
            rejections[id].error
          );
        }
      }
    }
    function onHandled(id) {
      if (rejections[id].logged) {
        if (options.onHandled) {
          options.onHandled(rejections[id].displayId, rejections[id].error);
        } else if (!rejections[id].onUnhandled) {
          console.warn(
            'Promise Rejection Handled (id: ' + rejections[id].displayId + '):'
          );
          console.warn(
            '  This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' +
            rejections[id].displayId + '.'
          );
        }
      }
    }
  }
  
  function logError(id, error) {
    console.warn('Possible Unhandled Promise Rejection (id: ' + id + '):');
    var errStr = (error && (error.stack || error)) + '';
    errStr.split('\n').forEach(function (line) {
      console.warn('  ' + line);
    });
  }
  
  function matchWhitelist(error, list) {
    return list.some(function (cls) {
      return error instanceof cls;
    });
  }