-
Notifications
You must be signed in to change notification settings - Fork 13
/
Ouch.js
145 lines (126 loc) · 3.56 KB
/
Ouch.js
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
/**
* Ouch.js
*
* @author: Harish Anchu <harishanchu@gmail.com>
* @copyright 2015, Harish Anchu. All rights reserved.
* @license Licensed under MIT (https://github.com/quorrajs/Ouch/blob/master/LICENSE)
*/
var Inspector = require('./exception/Inspector');
var _ = require('lodash');
var PrettyPageHandler = require('./handler/PrettyPageHandler');
var JsonResponseHandler = require('./handler/JsonResponseHandler');
var Handler = require('./handler/Handler');
var CallbackHandler = require('./handler/CallbackHandler');
/**
* @param {Array} handlerStack
* @constructor
*/
function Ouch(handlerStack) {
/**
* Stores error handlers
* @var {Array} handlerStack
* @protected
*/
this.__handlerStack = handlerStack || [];
}
/**
* Error handler classes
*
* @type {{PrettyPageHandler: (PrettyPageHandler)}}
*/
Ouch.handlers = {
BaseHandler: Handler,
CallbackHandler: CallbackHandler,
PrettyPageHandler: PrettyPageHandler,
JsonResponseHandler: JsonResponseHandler
};
/**
* Returns an array with all handlers, in the order they were added to the stack.
*
* @returns {Array}
*/
Ouch.prototype.getHandlers = function () {
return this.__handlerStack;
};
/**
* Pushes a handler to the end of the stack.
*
* @throws TypeError If argument is not callable or instance of HandlerInterface
* @param handler
* @returns {Ouch}
*/
Ouch.prototype.pushHandler = function (handler) {
if (_.isFunction(handler)){
handler = new CallbackHandler(handler)
} else if(!(handler instanceof Handler)) {
throw new TypeError("Argument must be a callable, or should be an instance of 'CallbackHandler'")
}
this.__handlerStack.push(handler);
return this;
};
/**
* Removes the last handler in the stack and returns it.
* Returns undefined if there"s nothing else to pop.
* @returns {function|Object|undefined}
*/
Ouch.prototype.popHandler = function () {
return this.__handlerStack.pop();
};
/**
* Clears all handlers in the handlerStack.
*
* @returns {Ouch}
*/
Ouch.prototype.clearHandlers = function () {
this.__handlerStack = [];
return this;
};
/**
* @param {Error|String|Object} exception
* @returns Inspector
* @protected
*/
Ouch.prototype.__getInspector = function (exception) {
return new Inspector(exception);
};
/**
* Handles an exception, ultimately generating a Ouch error
* page. Responses from each handler will be pushed into an array
* and will be sent along to the callback if present as first argument.
*
* @param {Error} exception
* @param {function} CB
* @param {Object} request
* @param {Object} response
*/
Ouch.prototype.handleException = function (exception, request, response, CB) {
if (!request) {
request = null;
}
if (!response) {
response = null;
}
if (!CB) {
CB = null;
}
(function (inspector, handlerStack, self) {
var output = [];
function next(handleResponse) {
output.push(handleResponse);
if ((arguments.length > 1 && arguments[1] === Handler.QUIT) || !handlerStack.length) {
if (CB) {
CB(output.slice(1));
}
} else {
var handler = handlerStack.shift();
handler.setRun(self);
handler.setInspector(inspector);
handler.setRequest(request);
handler.setResponse(response);
handler.handle(next);
}
}
next();
})(this.__getInspector(exception), this.__handlerStack.slice(0), this)
};
module.exports = Ouch;