strong-error-handler 2.3.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.md +28 -0
- package/README.md +31 -0
- package/index.d.ts +64 -0
- package/intl/cs/messages.json +5 -0
- package/intl/pl/messages.json +5 -0
- package/intl/ru/messages.json +5 -0
- package/lib/content-negotiation.js +1 -1
- package/lib/data-builder.js +18 -24
- package/lib/handler.js +37 -21
- package/package.json +13 -12
package/CHANGES.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
2018-08-30, Version 3.2.0
|
|
2
|
+
=========================
|
|
3
|
+
|
|
4
|
+
* Add type definition and writeErrorToResponse (shimks)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
2018-07-16, Version 3.1.0
|
|
8
|
+
=========================
|
|
9
|
+
|
|
10
|
+
* [WebFM] cs/pl/ru translation (candytangnb)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
2018-06-11, Version 3.0.0
|
|
14
|
+
=========================
|
|
15
|
+
|
|
16
|
+
* Allow safeFields to work with arrays (shimks)
|
|
17
|
+
|
|
18
|
+
* run lint (shimks)
|
|
19
|
+
|
|
20
|
+
* drop node 4 from travis and update dependencies (shimks)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
2018-03-05, Version 2.3.2
|
|
24
|
+
=========================
|
|
25
|
+
|
|
26
|
+
* Undefined safeFields revert to data #71 (Zak Barbuto)
|
|
27
|
+
|
|
28
|
+
|
|
1
29
|
2018-01-25, Version 2.3.1
|
|
2
30
|
=========================
|
|
3
31
|
|
package/README.md
CHANGED
|
@@ -12,6 +12,14 @@ In production mode, `strong-error-handler` omits details from error responses to
|
|
|
12
12
|
|
|
13
13
|
In debug mode, `strong-error-handler` returns full error stack traces and internal details of any error objects to the client in the HTTP responses.
|
|
14
14
|
|
|
15
|
+
## Supported versions
|
|
16
|
+
|
|
17
|
+
Current|Long Term Support|Maintenance
|
|
18
|
+
:-:|:-:|:-:
|
|
19
|
+
3.x|2.x|1.x
|
|
20
|
+
|
|
21
|
+
Learn more about our LTS plan in [docs](http://loopback.io/doc/en/contrib/Long-term-support.html).
|
|
22
|
+
|
|
15
23
|
## Installation
|
|
16
24
|
|
|
17
25
|
```bash
|
|
@@ -38,6 +46,29 @@ app.use(errorHandler({
|
|
|
38
46
|
app.listen(3000);
|
|
39
47
|
```
|
|
40
48
|
|
|
49
|
+
The module also exports `writeErrorToResponse`, a non-middleware flavor of the
|
|
50
|
+
error handler:
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
const http = require('http');
|
|
54
|
+
const writeErrorToResponse = require('strong-error-handler')
|
|
55
|
+
.writeErrorToResponse;
|
|
56
|
+
const errHandlingOptions = {debug: process.env.NODE_ENV === 'development'}
|
|
57
|
+
|
|
58
|
+
http
|
|
59
|
+
.createServer((req, res) => {
|
|
60
|
+
if (errShouldBeThrown) {
|
|
61
|
+
writeErrorToResponse(
|
|
62
|
+
new Error('something went wrong'),
|
|
63
|
+
req,
|
|
64
|
+
res,
|
|
65
|
+
errHandlingOptions,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
.listen(3000);
|
|
70
|
+
```
|
|
71
|
+
|
|
41
72
|
In LoopBack applications, add the following entry to `server/middleware.json`:
|
|
42
73
|
|
|
43
74
|
```json
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2018. All Rights Reserved.
|
|
2
|
+
// Node module: strong-error-handler
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
// Type definitions for strong-error-handler 3.x
|
|
7
|
+
// Project: https://github.com/strongloop/strong-error-handler
|
|
8
|
+
// Definitions by: Kyusung Shim <https://github.com/shimks>
|
|
9
|
+
// TypeScript Version: 3.0
|
|
10
|
+
|
|
11
|
+
import * as Express from 'express';
|
|
12
|
+
|
|
13
|
+
export = errorHandlerFactory;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a middleware function for error-handling
|
|
17
|
+
* @param options Options for error handler settings
|
|
18
|
+
*/
|
|
19
|
+
declare function errorHandlerFactory(
|
|
20
|
+
options?: errorHandlerFactory.ErrorHandlerOptions
|
|
21
|
+
): errorHandlerFactory.StrongErrorHandler;
|
|
22
|
+
|
|
23
|
+
declare namespace errorHandlerFactory {
|
|
24
|
+
/**
|
|
25
|
+
* Writes thrown error to response
|
|
26
|
+
* @param err Error to handle
|
|
27
|
+
* @param req Incoming request
|
|
28
|
+
* @param res Response
|
|
29
|
+
* @param options Options for error handler settings
|
|
30
|
+
*/
|
|
31
|
+
function writeErrorToResponse(
|
|
32
|
+
err: Error,
|
|
33
|
+
req: Express.Request,
|
|
34
|
+
res: Express.Response,
|
|
35
|
+
options?: ErrorWriterOptions
|
|
36
|
+
): void;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Error-handling middleware function. Includes server-side logging
|
|
40
|
+
*/
|
|
41
|
+
type StrongErrorHandler = (
|
|
42
|
+
err: Error,
|
|
43
|
+
req: Express.Request,
|
|
44
|
+
res: Express.Response,
|
|
45
|
+
next: (err?: any) => void
|
|
46
|
+
) => void;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Options for writing errors to the response
|
|
50
|
+
*/
|
|
51
|
+
interface ErrorWriterOptions {
|
|
52
|
+
debug?: boolean;
|
|
53
|
+
safeFields?: string[];
|
|
54
|
+
defaultType?: string;
|
|
55
|
+
negotiateContentType?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Options for error-handling
|
|
60
|
+
*/
|
|
61
|
+
interface ErrorHandlerOptions extends ErrorWriterOptions {
|
|
62
|
+
log?: boolean;
|
|
63
|
+
}
|
|
64
|
+
}
|
package/lib/data-builder.js
CHANGED
|
@@ -8,16 +8,18 @@
|
|
|
8
8
|
var cloneAllProperties = require('../lib/clone.js');
|
|
9
9
|
var httpStatus = require('http-status');
|
|
10
10
|
|
|
11
|
-
module.exports =
|
|
11
|
+
module.exports = buildResponseData;
|
|
12
|
+
|
|
13
|
+
function buildResponseData(err, options) {
|
|
12
14
|
// Debugging mode is disabled by default. When turned on (in dev),
|
|
13
15
|
// all error properties (including) stack traces are sent in the response
|
|
14
|
-
|
|
16
|
+
const isDebugMode = options.debug;
|
|
15
17
|
|
|
16
|
-
if (Array.isArray(err)
|
|
17
|
-
|
|
18
|
+
if (Array.isArray(err)) {
|
|
19
|
+
return serializeArrayOfErrors(err, options);
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
const data = Object.create(null);
|
|
21
23
|
fillStatusCode(data, err);
|
|
22
24
|
|
|
23
25
|
if (typeof err !== 'object') {
|
|
@@ -29,35 +31,25 @@ module.exports = function buildResponseData(err, options) {
|
|
|
29
31
|
|
|
30
32
|
if (isDebugMode) {
|
|
31
33
|
fillDebugData(data, err);
|
|
32
|
-
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (data.statusCode >= 400 && data.statusCode <= 499) {
|
|
33
38
|
fillBadRequestError(data, err);
|
|
34
39
|
} else {
|
|
35
40
|
fillInternalError(data, err);
|
|
36
41
|
}
|
|
37
42
|
|
|
38
|
-
|
|
43
|
+
const safeFields = options.safeFields || [];
|
|
39
44
|
fillSafeFields(data, err, safeFields);
|
|
40
45
|
|
|
41
46
|
return data;
|
|
42
47
|
};
|
|
43
48
|
|
|
44
|
-
function serializeArrayOfErrors(errors) {
|
|
45
|
-
|
|
46
|
-
for (var ix in errors) {
|
|
47
|
-
var err = errors[ix];
|
|
48
|
-
if (typeof err !== 'object') {
|
|
49
|
-
details.push('' + err);
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
var data = {};
|
|
54
|
-
cloneAllProperties(data, err);
|
|
55
|
-
delete data.statusCode;
|
|
56
|
-
details.push(data);
|
|
57
|
-
}
|
|
58
|
-
|
|
49
|
+
function serializeArrayOfErrors(errors, options) {
|
|
50
|
+
const details = errors.map(e => buildResponseData(e, options));
|
|
59
51
|
return {
|
|
60
|
-
|
|
52
|
+
statusCode: 500,
|
|
61
53
|
message: 'Failed with multiple errors, ' +
|
|
62
54
|
'see `details` for more information.',
|
|
63
55
|
details: details,
|
|
@@ -91,6 +83,8 @@ function fillSafeFields(data, err, safeFields) {
|
|
|
91
83
|
}
|
|
92
84
|
|
|
93
85
|
safeFields.forEach(function(field) {
|
|
94
|
-
|
|
86
|
+
if (err[field] !== undefined) {
|
|
87
|
+
data[field] = err[field];
|
|
88
|
+
}
|
|
95
89
|
});
|
|
96
90
|
}
|
package/lib/handler.js
CHANGED
|
@@ -23,7 +23,7 @@ function noop() {
|
|
|
23
23
|
* @param {Object} options
|
|
24
24
|
* @returns {Function}
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
function createStrongErrorHandler(options) {
|
|
27
27
|
options = options || {};
|
|
28
28
|
|
|
29
29
|
debug('Initializing with options %j', options);
|
|
@@ -32,31 +32,47 @@ exports = module.exports = function createStrongErrorHandler(options) {
|
|
|
32
32
|
var logError = options.log !== false ? logToConsole : noop;
|
|
33
33
|
|
|
34
34
|
return function strongErrorHandler(err, req, res, next) {
|
|
35
|
-
debug('Handling %s', err.stack || err);
|
|
36
|
-
|
|
37
35
|
logError(req, err);
|
|
36
|
+
writeErrorToResponse(err, req, res, options);
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Writes thrown error to response
|
|
42
|
+
*
|
|
43
|
+
* @param {Error} err
|
|
44
|
+
* @param {Express.Request} req
|
|
45
|
+
* @param {Express.Response} res
|
|
46
|
+
* @param {Object} options
|
|
47
|
+
*/
|
|
48
|
+
function writeErrorToResponse(err, req, res, options) {
|
|
49
|
+
debug('Handling %s', err.stack || err);
|
|
50
|
+
|
|
51
|
+
options = options || {};
|
|
38
52
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
if (res._header) {
|
|
54
|
+
debug('Response was already sent, closing the underlying connection');
|
|
55
|
+
return req.socket.destroy();
|
|
56
|
+
}
|
|
43
57
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
// this will alter the err object, to handle when res.statusCode is an error
|
|
59
|
+
if (!err.status && !err.statusCode && res.statusCode >= 400)
|
|
60
|
+
err.statusCode = res.statusCode;
|
|
47
61
|
|
|
48
|
-
|
|
49
|
-
|
|
62
|
+
var data = buildResponseData(err, options);
|
|
63
|
+
debug('Response status %s data %j', data.statusCode, data);
|
|
50
64
|
|
|
51
|
-
|
|
52
|
-
|
|
65
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
66
|
+
res.statusCode = data.statusCode;
|
|
53
67
|
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
var sendResponse = negotiateContentProducer(req, warn, options);
|
|
69
|
+
sendResponse(res, data);
|
|
56
70
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
};
|
|
71
|
+
function warn(msg) {
|
|
72
|
+
res.header('X-Warning', msg);
|
|
73
|
+
debug(msg);
|
|
74
|
+
}
|
|
62
75
|
};
|
|
76
|
+
|
|
77
|
+
exports = module.exports = createStrongErrorHandler;
|
|
78
|
+
exports.writeErrorToResponse = writeErrorToResponse;
|
package/package.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"name": "strong-error-handler",
|
|
3
3
|
"description": "Error handler for use in development and production environments.",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "3.2.0",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": ">=
|
|
7
|
+
"node": ">=6"
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -17,20 +17,21 @@
|
|
|
17
17
|
"posttest": "npm run lint"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
+
"@types/express": "^4.16.0",
|
|
20
21
|
"accepts": "^1.3.3",
|
|
21
|
-
"debug": "^
|
|
22
|
-
"ejs": "^2.
|
|
23
|
-
"http-status": "^1.
|
|
22
|
+
"debug": "^3.1.0",
|
|
23
|
+
"ejs": "^2.6.1",
|
|
24
|
+
"http-status": "^1.1.2",
|
|
24
25
|
"js2xmlparser": "^3.0.0",
|
|
25
|
-
"strong-globalize": "^
|
|
26
|
+
"strong-globalize": "^4.1.0"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
|
-
"chai": "^
|
|
29
|
-
"eslint": "^
|
|
30
|
-
"eslint-config-loopback": "^
|
|
31
|
-
"express": "^4.
|
|
32
|
-
"mocha": "^
|
|
33
|
-
"supertest": "^3.
|
|
29
|
+
"chai": "^4.1.2",
|
|
30
|
+
"eslint": "^4.19.1",
|
|
31
|
+
"eslint-config-loopback": "^10.0.0",
|
|
32
|
+
"express": "^4.16.3",
|
|
33
|
+
"mocha": "^5.2.0",
|
|
34
|
+
"supertest": "^3.1.0"
|
|
34
35
|
},
|
|
35
36
|
"browser": {
|
|
36
37
|
"strong-error-handler": false
|