Repository navigation
Expand file tree
/
Copy pathangular-error-handler.js
More file actions
172 lines (144 loc) · 5.89 KB
/
Copy pathangular-error-handler.js
File metadata and controls
172 lines (144 loc) · 5.89 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var errorNotifier = require('./error-notifier');
angular
.module('ngErrorHandler', [])
.factory('errorNotifier', errorNotifier)
.provider('errorHandler', errorHandler);
/* @ngInject */
function errorHandler() {
var handledServices = {}; // Stores the manually handled services
var isFunction = angular.isFunction.bind(angular);
var debug = true; // Determines if we should print logs
var decorator = function (serviceName) {
return ['$delegate', '$injector', function ($delegate, $injector) {
// Loops through all the properties of the service
// and check if it's a function, before wrapping it
// with our generic error handler
for (var prop in $delegate) {
var service = { value: $delegate, name: serviceName };
if (!isFunction($delegate[prop])) continue;
$delegate[prop] = decorate($injector, service, $delegate[prop]);
}
return $delegate;
}];
};
var decorate = function ($injector, service, fn) {
// Wraps the service function with our generic error handler
return angular.extend(function() {
var handler = $injector.get('errorHandler');
return handler.wrap(service, fn, arguments);
}, fn);
};
return {
debugEnabled: debugEnabled,
handle: handle,
$get: ['$q', 'errorNotifier', factory]
};
function debugEnabled(enable) {
debug = !!enable;
}
function handle($provide, services) {
if (angular.isArray(services)) autoHandling($provide, services);
else if (angular.isObject(services)) manualHandling($provide, services);
else console.error('ngErrorHandler: Invalid options.');
}
function autoHandling($provide, services) {
var len = services.length;
for (var i = 0; i < len; i++) {
$provide.decorator(services[i], decorator(services[i]));
}
}
function manualHandling($provide, services) {
angular.forEach(services, function (value, key) {
handledServices[key] = {};
var len = value.length;
for (var i = 0; i < len; i++) {
// Store the function that is manually handled
handledServices[key][value[i]] = true;
}
$provide.decorator(key, decorator(key));
});
}
function factory($q, errorNotifier) {
return {
wrap: wrap
}
function wrap(service, fn, args) {
var serviceName = service.name;
var fnName = fn.name;
var result;
try {
result = fn.apply(service.value, args);
} catch (error) {
// Catch synchronous errors
log('ngErrorHandler: Exception @', serviceName, '->', fnName, error);
errorNotifier.broadcast(error);
throw error;
/*
* TODO: Catching exceptions with the choice to
* rethrow the exception or continue the execution
*/
// if (isServiceFnManuallyHandled(serviceName, fnName)) {
// log('ngErrorHandler:', 'Error is manually handled.');
// // Just throw the exception again, because it's manually handled
// throw error;
// }
// log('ngErrorHandler:', 'Exception is automatically handled.');
// return
}
// Catch asynchronous errors
var promise = result && result.$promise || result;
if (promise && isFunction(promise.then) && isFunction(promise.catch)) {
return handleAsync(promise, serviceName, fnName);
}
return result;
}
function handleAsync(promise, service, fn) {
return promise.catch(function (error) {
log('ngErrorHandler: Async Error @', service, '->', fn, error);
if (isServiceFnManuallyHandled(service, fn)) {
// Just reject the error again, so that the
// user can handle it manually
log('ngErrorHandler:', 'Error is manually handled.');
return $q.reject(error);
}
log('ngErrorHandler:', 'Error is automatically handled.');
errorNotifier.broadcast(error);
// This prevents the execution of other promises chained to this call
return $q(function () {
return null;
});
});
}
function isServiceFnManuallyHandled(service, fn) {
return handledServices[service] && handledServices[service][fn];
}
function log() {
if (debug) console.log.apply(console, arguments);
}
}
}
},{"./error-notifier":2}],2:[function(require,module,exports){
'use strict';
/* @ngInject */
var errorNotifier = ['$rootScope', function ($rootScope) {
var events = {
error: 'error-occured'
};
var service = {
broadcast: broadcast,
on: on
};
return service;
function broadcast(error) {
$rootScope.$emit(events.error, error);
}
function on(cb) {
$rootScope.$on(events.error, function (event, error) {
cb(error);
});
}
}];
module.exports = errorNotifier;
},{}]},{},[1]);