1 | var _ = require('lodash');
|
2 | var utils = require('./utils');
|
3 | var errors = module.exports;
|
4 |
|
5 | var canCapture = typeof Error.captureStackTrace === 'function';
|
6 | var canStack = !!new Error().stack;
|
7 |
|
8 | function ErrorAbstract(msg, constructor, metadata) {
|
9 | this.message = msg;
|
10 |
|
11 | Error.call(this, this.message);
|
12 |
|
13 | if (canCapture) {
|
14 | Error.captureStackTrace(this, constructor);
|
15 | } else if (canStack) {
|
16 | this.stack = new Error().stack;
|
17 | } else {
|
18 | this.stack = '';
|
19 | }
|
20 |
|
21 | if (metadata) {
|
22 | _.assign(this, metadata);
|
23 |
|
24 | this.toString = function() {
|
25 | return msg + ' :: ' + JSON.stringify(metadata);
|
26 | };
|
27 |
|
28 | this.toJSON = function() {
|
29 | return _.assign(
|
30 | {
|
31 | msg: msg,
|
32 | },
|
33 | metadata
|
34 | );
|
35 | };
|
36 | }
|
37 | }
|
38 | errors._Abstract = ErrorAbstract;
|
39 | utils.inherits(ErrorAbstract, Error);
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 | errors.ConnectionFault = function ConnectionFault(msg) {
|
46 | ErrorAbstract.call(this, msg || 'Connection Failure', errors.ConnectionFault);
|
47 | };
|
48 | utils.inherits(errors.ConnectionFault, ErrorAbstract);
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | errors.NoConnections = function NoConnections(msg) {
|
55 | ErrorAbstract.call(
|
56 | this,
|
57 | msg || 'No Living connections',
|
58 | errors.NoConnections
|
59 | );
|
60 | };
|
61 | utils.inherits(errors.NoConnections, ErrorAbstract);
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | errors.Generic = function Generic(msg, metadata) {
|
68 | ErrorAbstract.call(this, msg || 'Generic Error', errors.Generic, metadata);
|
69 | };
|
70 | utils.inherits(errors.Generic, ErrorAbstract);
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 | errors.RequestTimeout = function RequestTimeout(msg) {
|
77 | ErrorAbstract.call(this, msg || 'Request Timeout', errors.RequestTimeout);
|
78 | };
|
79 | utils.inherits(errors.RequestTimeout, ErrorAbstract);
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | errors.Serialization = function Serialization(msg) {
|
86 | ErrorAbstract.call(
|
87 | this,
|
88 | msg || 'Unable to parse/serialize body',
|
89 | errors.Serialization
|
90 | );
|
91 | };
|
92 | utils.inherits(errors.Serialization, ErrorAbstract);
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | errors.RequestTypeError = function RequestTypeError(feature) {
|
98 | ErrorAbstract.call(
|
99 | this,
|
100 | 'Cross-domain AJAX requests ' + feature + ' are not supported',
|
101 | errors.RequestTypeError
|
102 | );
|
103 | };
|
104 | utils.inherits(errors.RequestTypeError, ErrorAbstract);
|
105 |
|
106 | var statusCodes = [
|
107 | [300, 'Multiple Choices'],
|
108 | [301, 'Moved Permanently'],
|
109 | [302, 'Found'],
|
110 | [303, 'See Other'],
|
111 | [304, 'Not Modified'],
|
112 | [305, 'Use Proxy'],
|
113 | [307, 'Temporary Redirect'],
|
114 | [308, 'Permanent Redirect'],
|
115 | [400, 'Bad Request'],
|
116 | [401, 'Authentication Exception'],
|
117 | [402, 'Payment Required'],
|
118 | [403, ['Authorization Exception', 'Forbidden']],
|
119 | [404, 'Not Found'],
|
120 | [405, 'Method Not Allowed'],
|
121 | [406, 'Not Acceptable'],
|
122 | [407, 'Proxy Authentication Required'],
|
123 | [408, 'Request Timeout'],
|
124 | [409, 'Conflict'],
|
125 | [410, 'Gone'],
|
126 | [411, 'Length Required'],
|
127 | [412, 'Precondition Failed'],
|
128 | [413, 'Request Entity Too Large'],
|
129 | [414, 'Request URIToo Long'],
|
130 | [415, 'Unsupported Media Type'],
|
131 | [416, 'Requested Range Not Satisfiable'],
|
132 | [417, 'Expectation Failed'],
|
133 | [418, 'Im ATeapot'],
|
134 | [421, 'Too Many Connections From This IP'],
|
135 | [426, 'Upgrade Required'],
|
136 | [429, 'Too Many Requests'],
|
137 | [450, 'Blocked By Windows Parental Controls'],
|
138 | [494, 'Request Header Too Large'],
|
139 | [497, 'HTTPTo HTTPS'],
|
140 | [499, 'Client Closed Request'],
|
141 | [500, 'Internal Server Error'],
|
142 | [501, 'Not Implemented'],
|
143 | [502, 'Bad Gateway'],
|
144 | [503, 'Service Unavailable'],
|
145 | [504, 'Gateway Timeout'],
|
146 | [505, 'HTTPVersion Not Supported'],
|
147 | [506, 'Variant Also Negotiates'],
|
148 | [510, 'Not Extended'],
|
149 | ];
|
150 |
|
151 | _.each(statusCodes, function createStatusCodeError(tuple) {
|
152 | var status = tuple[0];
|
153 | var names = tuple[1];
|
154 | var allNames = [].concat(names, status);
|
155 | var primaryName = allNames[0];
|
156 | var className = utils.studlyCase(primaryName);
|
157 | allNames = _.uniq(allNames.concat(className));
|
158 |
|
159 | function StatusCodeError(msg, metadata) {
|
160 | this.status = status;
|
161 | this.displayName = className;
|
162 |
|
163 | var esErrObject = null;
|
164 | if (_.isPlainObject(msg)) {
|
165 | esErrObject = msg;
|
166 | msg = null;
|
167 | }
|
168 |
|
169 | if (!esErrObject) {
|
170 |
|
171 |
|
172 |
|
173 | ErrorAbstract.call(this, msg || primaryName, StatusCodeError, metadata);
|
174 | return this;
|
175 | }
|
176 |
|
177 | msg = [].concat(esErrObject.root_cause || []).reduce(function(memo, cause) {
|
178 | if (memo) memo += ' (and) ';
|
179 |
|
180 | memo += '[' + cause.type + '] ' + cause.reason;
|
181 |
|
182 | var extraData = _.omit(cause, ['type', 'reason']);
|
183 | if (_.size(extraData)) {
|
184 | memo += ', with ' + prettyPrint(extraData);
|
185 | }
|
186 |
|
187 | return memo;
|
188 | }, '');
|
189 |
|
190 | if (!msg) {
|
191 | if (esErrObject.type) msg += '[' + esErrObject.type + '] ';
|
192 | if (esErrObject.reason) msg += esErrObject.reason;
|
193 | }
|
194 |
|
195 | ErrorAbstract.call(this, msg || primaryName, StatusCodeError, metadata);
|
196 | return this;
|
197 | }
|
198 | utils.inherits(StatusCodeError, ErrorAbstract);
|
199 |
|
200 | allNames.forEach(function(name) {
|
201 | errors[name] = StatusCodeError;
|
202 | });
|
203 | });
|
204 |
|
205 | function prettyPrint(data) {
|
206 | const path = [];
|
207 | return (function print(v) {
|
208 | if (typeof v === 'object') {
|
209 | if (path.indexOf(v) > -1) return '[circular]';
|
210 | path.push(v);
|
211 | try {
|
212 | return (
|
213 | '{ ' +
|
214 | _.map(v, function(subv, name) {
|
215 | return name + '=' + print(subv);
|
216 | }).join(' & ') +
|
217 | ' }'
|
218 | );
|
219 | } finally {
|
220 | path.pop();
|
221 | }
|
222 | } else {
|
223 | return JSON.stringify(v);
|
224 | }
|
225 | })(data);
|
226 | }
|