Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit a3ad826

Browse files
author
Thomas Grainger
committed
fix($q): Add traceback to unhandled promise rejections, Fixes: #14631
1 parent f768da2 commit a3ad826

File tree

2 files changed

+66
-40
lines changed

2 files changed

+66
-40
lines changed

Diff for: src/ng/q.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,11 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
381381
if (!toCheck.pur) {
382382
toCheck.pur = true;
383383
var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value);
384-
exceptionHandler(errorMessage);
384+
if (toCheck.value instanceof Error) {
385+
exceptionHandler(toCheck.value, errorMessage);
386+
} else {
387+
exceptionHandler(errorMessage);
388+
}
385389
}
386390
}
387391
}

Diff for: test/ng/qSpec.js

+61-39
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,14 @@ describe('q', function() {
181181
};
182182

183183

184-
function exceptionHandler(reason) {
185-
exceptionHandlerCalls.push(reason);
186-
}
187-
188-
189-
function exceptionHandlerStr() {
190-
return exceptionHandlerCalls.join('; ');
184+
function exceptionHandler(exception, reason) {
185+
if (typeof reason === 'undefined') {
186+
exceptionHandlerCalls.push({ reason: exception });
187+
} else {
188+
exceptionHandlerCalls.push({ reason: reason, exception: exception });
189+
}
191190
}
192191

193-
194192
beforeEach(function() {
195193
q = qFactory(mockNextTick.nextTick, exceptionHandler, true);
196194
q_no_error = qFactory(mockNextTick.nextTick, exceptionHandler, false);
@@ -2167,45 +2165,69 @@ describe('q', function() {
21672165

21682166

21692167
describe('when exceptionHandler is called', function() {
2170-
it('should log an unhandled rejected promise', function() {
2171-
var defer = q.defer();
2172-
defer.reject('foo');
2173-
mockNextTick.flush();
2174-
expect(exceptionHandlerStr()).toBe('Possibly unhandled rejection: foo');
2175-
});
2168+
var exceptionEg = new Error('Fail');
2169+
var exceptionStr = toDebugString(exceptionEg);
2170+
var fixtures = [
2171+
{
2172+
type: 'exception',
2173+
value: exceptionEg,
2174+
expected: {
2175+
exception: exceptionEg,
2176+
reason: 'Possibly unhandled rejection: ' + exceptionStr
2177+
}
2178+
},
2179+
{
2180+
type: 'plain value',
2181+
value: 'foo',
2182+
expected: {
2183+
reason: 'Possibly unhandled rejection: foo'
2184+
}
2185+
}
2186+
];
2187+
forEach(fixtures, function(fixture) {
2188+
var type = fixture.type;
2189+
var value = fixture.value;
2190+
var expected = fixture.expected;
2191+
it('should log an unhandled' + type + ' rejected promise', function() {
2192+
var defer = q.defer();
2193+
defer.reject(value);
2194+
mockNextTick.flush();
2195+
expect(exceptionHandlerCalls).toEqual([expected]);
2196+
});
21762197

21772198

2178-
it('should not log an unhandled rejected promise if disabled', function() {
2179-
var defer = q_no_error.defer();
2180-
defer.reject('foo');
2181-
expect(exceptionHandlerStr()).toBe('');
2182-
});
2199+
it('should not log an unhandled' + type + ' rejected promise if disabled', function() {
2200+
var defer = q_no_error.defer();
2201+
defer.reject(value);
2202+
expect(exceptionHandlerCalls).toEqual([]);
2203+
});
21832204

21842205

2185-
it('should log a handled rejected promise on a promise without rejection callbacks', function() {
2186-
var defer = q.defer();
2187-
defer.promise.then(noop);
2188-
defer.reject('foo');
2189-
mockNextTick.flush();
2190-
expect(exceptionHandlerStr()).toBe('Possibly unhandled rejection: foo');
2191-
});
2206+
it('should log a handled' + type + ' rejected promise on a promise without rejection callbacks', function() {
2207+
var defer = q.defer();
2208+
defer.promise.then(noop);
2209+
defer.reject(value);
2210+
mockNextTick.flush();
2211+
expect(exceptionHandlerCalls).toEqual([expected]);
2212+
});
21922213

21932214

2194-
it('should not log a handled rejected promise', function() {
2195-
var defer = q.defer();
2196-
defer.promise.catch(noop);
2197-
defer.reject('foo');
2198-
mockNextTick.flush();
2199-
expect(exceptionHandlerStr()).toBe('');
2200-
});
2215+
it('should not log a handled' + type + 'rejected promise', function() {
2216+
var defer = q.defer();
2217+
defer.promise.catch(noop);
2218+
defer.reject(value);
2219+
mockNextTick.flush();
2220+
expect(exceptionHandlerCalls).toEqual([]);
2221+
});
22012222

22022223

2203-
it('should not log a handled rejected promise that is handled in a future tick', function() {
2204-
var defer = q.defer();
2205-
defer.promise.catch(noop);
2206-
defer.resolve(q.reject('foo'));
2207-
mockNextTick.flush();
2208-
expect(exceptionHandlerStr()).toBe('');
2224+
it('should not log a handled' + type + ' rejected promise that is handled in a future tick', function() {
2225+
var defer = q.defer();
2226+
defer.promise.catch(noop);
2227+
defer.resolve(q.reject(value));
2228+
mockNextTick.flush();
2229+
expect(exceptionHandlerCalls).toEqual([]);
2230+
});
22092231
});
22102232
});
22112233
});

0 commit comments

Comments
 (0)