strong-error-handler 1.2.1 → 2.3.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/.github/ISSUE_TEMPLATE.md +22 -21
- package/.github/PULL_REQUEST_TEMPLATE.md +5 -4
- package/CHANGES.md +44 -0
- package/CODEOWNERS +5 -0
- package/README.md +64 -21
- package/lib/content-negotiation.js +16 -4
- package/lib/data-builder.js +1 -0
- package/lib/handler.js +6 -1
- package/package.json +12 -9
- package/.npmignore +0 -35
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
|
|
2
|
+
Questions:
|
|
3
|
+
https://groups.google.com/forum/#!forum/loopbackjs
|
|
3
4
|
https://gitter.im/strongloop/loopback
|
|
4
|
-
|
|
5
|
-
- Immediate support is available through our subscription plans, see
|
|
5
|
+
Immediate support:
|
|
6
6
|
https://strongloop.com/api-connect-faqs/
|
|
7
|
+
https://strongloop.com/node-js/subscription-plans/
|
|
7
8
|
-->
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
# Description/Steps to reproduce
|
|
10
11
|
|
|
11
12
|
<!--
|
|
12
|
-
|
|
13
|
+
If feature: A description of the feature
|
|
14
|
+
If bug: Steps to reproduce
|
|
13
15
|
-->
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
- [ ] Feature request
|
|
17
|
-
|
|
18
|
-
### Description of feature (or steps to reproduce if bug)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
### Link to sample repo to reproduce issue (if bug)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
### Expected result
|
|
17
|
+
# Link to reproduction sandbox
|
|
27
18
|
|
|
19
|
+
<!--
|
|
20
|
+
Link to an app sandbox for reproduction
|
|
28
21
|
|
|
22
|
+
Note: Failure to provide a sandbox application for reproduction purposes will result in the issue being closed.
|
|
23
|
+
-->
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
# Expected result
|
|
33
26
|
|
|
34
|
-
|
|
27
|
+
<!--
|
|
28
|
+
Also include actual results if bug
|
|
29
|
+
-->
|
|
35
30
|
|
|
31
|
+
# Additional information
|
|
36
32
|
|
|
33
|
+
<!--
|
|
34
|
+
Copy+paste the output of these two commands:
|
|
35
|
+
node -e 'console.log(process.platform, process.arch, process.versions.node)'
|
|
36
|
+
npm ls --prod --depth 0 | grep loopback
|
|
37
|
+
-->
|
|
@@ -6,17 +6,18 @@
|
|
|
6
6
|
<!--
|
|
7
7
|
Please use the following link syntaxes:
|
|
8
8
|
|
|
9
|
-
- #49 (to reference issues in the current repository)
|
|
10
|
-
- strongloop/loopback#49 (to reference issues in another repository)
|
|
9
|
+
- connect to #49 (to reference issues in the current repository)
|
|
10
|
+
- connect to strongloop/loopback#49 (to reference issues in another repository)
|
|
11
11
|
-->
|
|
12
12
|
|
|
13
|
-
-
|
|
13
|
+
- connect to <link_to_referenced_issue>
|
|
14
14
|
|
|
15
15
|
### Checklist
|
|
16
16
|
|
|
17
17
|
<!--
|
|
18
|
-
Please mark your choice with an "x" (i.e. [x], see
|
|
18
|
+
- Please mark your choice with an "x" (i.e. [x], see
|
|
19
19
|
https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments)
|
|
20
|
+
- PR's without test coverage will be closed.
|
|
20
21
|
-->
|
|
21
22
|
|
|
22
23
|
- [ ] New tests added or existing tests modified to cover all changes
|
package/CHANGES.md
CHANGED
|
@@ -1,3 +1,47 @@
|
|
|
1
|
+
2017-10-13, Version 2.3.0
|
|
2
|
+
=========================
|
|
3
|
+
|
|
4
|
+
* update strong-globalize to 3.1.0 (shimks)
|
|
5
|
+
|
|
6
|
+
* CODEOWNERS: add zbarbuto (Miroslav Bajtoš)
|
|
7
|
+
|
|
8
|
+
* Update Issue and PR Templates (#59) (Sakib Hasan)
|
|
9
|
+
|
|
10
|
+
* fixed json typo of server/middleware.json (karanssj4)
|
|
11
|
+
|
|
12
|
+
* Add CODEOWNER file (Diana Lau)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
2017-07-20, Version 2.2.0
|
|
16
|
+
=========================
|
|
17
|
+
|
|
18
|
+
* Add new option: negotiateContentType (Raj)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
2017-04-18, Version 2.1.0
|
|
22
|
+
=========================
|
|
23
|
+
|
|
24
|
+
* Bump js2xmlparser dependency to version 3.0.0 (Matthew O'Donoghue)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
2017-03-22, Version 2.0.0
|
|
28
|
+
=========================
|
|
29
|
+
|
|
30
|
+
* Fix markdown formatting in README (Miroslav Bajtoš)
|
|
31
|
+
|
|
32
|
+
* Fix the order of arguments in the jsdoc comment. (Charlie Schliesser)
|
|
33
|
+
|
|
34
|
+
* Update readme with added XML support (David Cheung)
|
|
35
|
+
|
|
36
|
+
* Add a machine-readable "code" property (Zak Barbuto)
|
|
37
|
+
|
|
38
|
+
* Upgrade dependencies to their latest versions (Miroslav Bajtoš)
|
|
39
|
+
|
|
40
|
+
* Describe "safeFields" option in README (Zak Barbuto)
|
|
41
|
+
|
|
42
|
+
* Drop support for Node v0.10/v0.12 (Miroslav Bajtoš)
|
|
43
|
+
|
|
44
|
+
|
|
1
45
|
2017-01-30, Version 1.2.1
|
|
2
46
|
=========================
|
|
3
47
|
|
package/CODEOWNERS
ADDED
package/README.md
CHANGED
|
@@ -7,7 +7,8 @@ In production mode, `strong-error-handler` omits details from error responses to
|
|
|
7
7
|
- For 5xx errors, the output contains only the status code and the status name from the HTTP specification.
|
|
8
8
|
- For 4xx errors, the output contains the full error message (`error.message`) and the contents of the `details`
|
|
9
9
|
property (`error.details`) that `ValidationError` typically uses to provide machine-readable details
|
|
10
|
-
about validation problems.
|
|
10
|
+
about validation problems. It also includes `error.code` to allow a machine-readable error code to be passed
|
|
11
|
+
through which could be used, for example, for translation.
|
|
11
12
|
|
|
12
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.
|
|
13
14
|
|
|
@@ -59,7 +60,7 @@ For details on configuration options, see below.
|
|
|
59
60
|
|
|
60
61
|
### Response format and content type
|
|
61
62
|
|
|
62
|
-
The `strong-error-handler` package supports HTML and
|
|
63
|
+
The `strong-error-handler` package supports JSON, HTML and XML responses:
|
|
63
64
|
|
|
64
65
|
- When the object is a standard Error object, it returns the string provided by the stack property in HTML/text
|
|
65
66
|
responses.
|
|
@@ -70,8 +71,9 @@ The content type of the response depends on the request's `Accepts` header.
|
|
|
70
71
|
|
|
71
72
|
- For Accepts header `json` or `application/json`, the response content type is JSON.
|
|
72
73
|
- For Accepts header `html` or `text/html`, the response content type is HTML.
|
|
74
|
+
- For Accepts header `xml` or `text/xml`, the response content type is XML.
|
|
73
75
|
|
|
74
|
-
*There are plans to support other formats such as
|
|
76
|
+
*There are plans to support other formats such as Plain-text.*
|
|
75
77
|
|
|
76
78
|
## Options
|
|
77
79
|
|
|
@@ -79,6 +81,9 @@ The content type of the response depends on the request's `Accepts` header.
|
|
|
79
81
|
| ---- | ---- | ---- | ---- |
|
|
80
82
|
| debug | Boolean | `false` | If `true`, HTTP responses include all error properties, including sensitive data such as file paths, URLs and stack traces. See [Example output](#example) below. |
|
|
81
83
|
| log | Boolean | `true` | If `true`, all errors are printed via `console.error`, including an array of fields (custom error properties) that are safe to include in response messages (both 4xx and 5xx). <br/> If `false`, sends only the error back in the response. |
|
|
84
|
+
| safeFields | [String] | `[]` | Specifies property names on errors that are allowed to be passed through in 4xx and 5xx responses. See [Safe error fields](#safe-error-fields) below. |
|
|
85
|
+
| defaultType | String | `"json"` | Specify the default response content type to use when the client does not provide any Accepts header.
|
|
86
|
+
| negotiateContentType | Boolean | true | Negotiate the response content type via Accepts request header. When disabled, strong-error-handler will always use the default content type when producing responses. Disabling content type negotiation is useful if you want to see JSON-formatted error responses in browsers, because browsers usually prefer HTML and XML over other content types.
|
|
82
87
|
|
|
83
88
|
### Customizing log format
|
|
84
89
|
|
|
@@ -116,7 +121,7 @@ Then in `server/middleware.json`, specify your custom error logging function as
|
|
|
116
121
|
"./middleware/error-logger": {},
|
|
117
122
|
"strong-error-handler": {
|
|
118
123
|
"params": {
|
|
119
|
-
log: false
|
|
124
|
+
"log": false
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
}
|
|
@@ -124,6 +129,34 @@ Then in `server/middleware.json`, specify your custom error logging function as
|
|
|
124
129
|
|
|
125
130
|
The default `middleware.development.json` file explicitly enables logging in strong-error-handler params, so you will need to change that file too.
|
|
126
131
|
|
|
132
|
+
### Safe error fields
|
|
133
|
+
|
|
134
|
+
By default, `strong-error-handler` will only pass through the `name`, `message` and `details` properties of an error. Additional error
|
|
135
|
+
properties may be allowed through on 4xx and 5xx status code errors using the `safeFields` option to pass in an array of safe field names:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
{
|
|
139
|
+
"final:after": {
|
|
140
|
+
"strong-error-handler": {
|
|
141
|
+
"params": {
|
|
142
|
+
"safeFields": ["errorCode"]
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Using the above configuration, an error containing an `errorCode` property will produce the following response:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
{
|
|
152
|
+
"error": {
|
|
153
|
+
"statusCode": 500,
|
|
154
|
+
"message": "Internal Server Error",
|
|
155
|
+
"errorCode": "INTERNAL_SERVER_ERROR"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
127
160
|
## Migration from old LoopBack error handler
|
|
128
161
|
|
|
129
162
|
NOTE: This is only required for applications scaffolded with old versions of the `slc loopback` tool.
|
|
@@ -140,34 +173,34 @@ To migrate a LoopBack 2.x application to use `strong-error-handler`:
|
|
|
140
173
|
"errorHandler": {
|
|
141
174
|
"disableStackTrace": false
|
|
142
175
|
}</pre>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
176
|
+
and replace it with:
|
|
177
|
+
<pre>
|
|
178
|
+
"remoting": {
|
|
179
|
+
...,
|
|
180
|
+
"rest": {
|
|
181
|
+
"handleErrors": false
|
|
182
|
+
}</pre>
|
|
150
183
|
1. In `server/middleware.json`, remove:
|
|
151
184
|
<pre>
|
|
152
185
|
"final:after": {
|
|
153
186
|
"loopback#errorHandler": {}
|
|
154
187
|
}</pre>
|
|
155
|
-
|
|
188
|
+
and replace it with:
|
|
156
189
|
<pre>
|
|
157
190
|
"final:after": {
|
|
158
191
|
"strong-error-handler": {}
|
|
159
192
|
}</pre>
|
|
160
193
|
1. Delete `server/middleware.production.json`.
|
|
161
194
|
1. Create `server/middleware.development.json` containing:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
195
|
+
<pre>
|
|
196
|
+
"final:after": {
|
|
197
|
+
"strong-error-handler": {
|
|
198
|
+
"params": {
|
|
199
|
+
"debug": true,
|
|
200
|
+
"log": true
|
|
201
|
+
}
|
|
168
202
|
}
|
|
169
203
|
}
|
|
170
|
-
}
|
|
171
204
|
</pre>
|
|
172
205
|
|
|
173
206
|
For more information, see
|
|
@@ -175,13 +208,13 @@ For more information, see
|
|
|
175
208
|
|
|
176
209
|
## Example
|
|
177
210
|
|
|
178
|
-
|
|
211
|
+
5xx error generated when `debug: false` :
|
|
179
212
|
|
|
180
213
|
```
|
|
181
214
|
{ error: { statusCode: 500, message: 'Internal Server Error' } }
|
|
182
215
|
```
|
|
183
216
|
|
|
184
|
-
|
|
217
|
+
The same error generated when `debug: true` :
|
|
185
218
|
|
|
186
219
|
```
|
|
187
220
|
{ error:
|
|
@@ -201,3 +234,13 @@ Error generated when `debug: true` :
|
|
|
201
234
|
at tryOnImmediate (timers.js:543:15)
|
|
202
235
|
at processImmediate [as _immediateCallback] (timers.js:523:5)' }}
|
|
203
236
|
```
|
|
237
|
+
|
|
238
|
+
4xx error generated when `debug: false` :
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
{ error:
|
|
242
|
+
{ statusCode: 422,
|
|
243
|
+
name: 'Unprocessable Entity',
|
|
244
|
+
message: 'Missing required fields',
|
|
245
|
+
code: 'MISSING_REQUIRED_FIELDS' }}
|
|
246
|
+
```
|
|
@@ -18,10 +18,11 @@ module.exports = negotiateContentProducer;
|
|
|
18
18
|
* to resolve the correct operation
|
|
19
19
|
*
|
|
20
20
|
* @param req request object
|
|
21
|
+
* @param {Function} logWarning a logger function for reporting warnings
|
|
21
22
|
* @param {Object} options options of strong-error-handler
|
|
22
|
-
* @returns {Function}
|
|
23
|
+
* @returns {Function} Operation function with signature `fn(res, data)`
|
|
23
24
|
*/
|
|
24
|
-
function negotiateContentProducer(req, options) {
|
|
25
|
+
function negotiateContentProducer(req, logWarning, options) {
|
|
25
26
|
var SUPPORTED_TYPES = [
|
|
26
27
|
'application/json', 'json',
|
|
27
28
|
'text/html', 'html',
|
|
@@ -55,6 +56,18 @@ function negotiateContentProducer(req, options) {
|
|
|
55
56
|
debug('Resolved content-type', resolvedContentType);
|
|
56
57
|
var contentType = resolvedContentType || defaultType;
|
|
57
58
|
|
|
59
|
+
if (options.negotiateContentType === false) {
|
|
60
|
+
if (SUPPORTED_TYPES.indexOf(options.defaultType) > -1) {
|
|
61
|
+
debug('Forcing options.defaultType `%s`',
|
|
62
|
+
options.defaultType);
|
|
63
|
+
contentType = options.defaultType;
|
|
64
|
+
} else {
|
|
65
|
+
debug('contentType: `%s` is not supported, ' +
|
|
66
|
+
'falling back to contentType: `%s`',
|
|
67
|
+
options.defaultType, contentType);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
58
71
|
// to receive _format from user's url param to overide the content type
|
|
59
72
|
// req.query (eg /api/Users/1?_format=json will overide content negotiation
|
|
60
73
|
// https://github.com/strongloop/strong-remoting/blob/ac3093dcfbb787977ca0229b0f672703859e52e1/lib/http-context.js#L643-L645
|
|
@@ -66,8 +79,7 @@ function negotiateContentProducer(req, options) {
|
|
|
66
79
|
// format passed through query but not supported
|
|
67
80
|
var msg = util.format('Response _format "%s" is not supported' +
|
|
68
81
|
'used "%s" instead"', query._format, defaultType);
|
|
69
|
-
|
|
70
|
-
debug(msg);
|
|
82
|
+
logWarning(msg);
|
|
71
83
|
}
|
|
72
84
|
}
|
|
73
85
|
|
package/lib/data-builder.js
CHANGED
package/lib/handler.js
CHANGED
|
@@ -51,7 +51,12 @@ exports = module.exports = function createStrongErrorHandler(options) {
|
|
|
51
51
|
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
52
52
|
res.statusCode = data.statusCode;
|
|
53
53
|
|
|
54
|
-
var sendResponse = negotiateContentProducer(req, options);
|
|
54
|
+
var sendResponse = negotiateContentProducer(req, warn, options);
|
|
55
55
|
sendResponse(res, data);
|
|
56
|
+
|
|
57
|
+
function warn(msg) {
|
|
58
|
+
res.header('X-Warning', msg);
|
|
59
|
+
debug(msg);
|
|
60
|
+
}
|
|
56
61
|
};
|
|
57
62
|
};
|
package/package.json
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
"name": "strong-error-handler",
|
|
3
3
|
"description": "Error handler for use in development and production environments.",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "2.3.0",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=4"
|
|
8
|
+
},
|
|
6
9
|
"repository": {
|
|
7
10
|
"type": "git",
|
|
8
11
|
"url": "https://github.com/strongloop/strong-error-handler.git"
|
|
@@ -17,17 +20,17 @@
|
|
|
17
20
|
"accepts": "^1.3.3",
|
|
18
21
|
"debug": "^2.2.0",
|
|
19
22
|
"ejs": "^2.4.2",
|
|
20
|
-
"http-status": "^0.
|
|
21
|
-
"js2xmlparser": "^
|
|
22
|
-
"strong-globalize": "^
|
|
23
|
+
"http-status": "^1.0.0",
|
|
24
|
+
"js2xmlparser": "^3.0.0",
|
|
25
|
+
"strong-globalize": "^3.1.0"
|
|
23
26
|
},
|
|
24
27
|
"devDependencies": {
|
|
25
|
-
"chai": "^
|
|
26
|
-
"eslint": "^
|
|
27
|
-
"eslint-config-loopback": "^
|
|
28
|
+
"chai": "^3.5.0",
|
|
29
|
+
"eslint": "^3.14.1",
|
|
30
|
+
"eslint-config-loopback": "^8.0.0",
|
|
28
31
|
"express": "^4.13.4",
|
|
29
|
-
"mocha": "^2.
|
|
30
|
-
"supertest": "^
|
|
32
|
+
"mocha": "^3.2.0",
|
|
33
|
+
"supertest": "^3.0.0"
|
|
31
34
|
},
|
|
32
35
|
"browser": {
|
|
33
36
|
"strong-error-handler": false
|
package/.npmignore
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Logs
|
|
2
|
-
logs
|
|
3
|
-
*.log
|
|
4
|
-
npm-debug.log*
|
|
5
|
-
|
|
6
|
-
# Runtime data
|
|
7
|
-
pids
|
|
8
|
-
*.pid
|
|
9
|
-
*.seed
|
|
10
|
-
|
|
11
|
-
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
12
|
-
lib-cov
|
|
13
|
-
|
|
14
|
-
# Coverage directory used by tools like istanbul
|
|
15
|
-
coverage
|
|
16
|
-
|
|
17
|
-
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
|
18
|
-
.grunt
|
|
19
|
-
|
|
20
|
-
# node-waf configuration
|
|
21
|
-
.lock-wscript
|
|
22
|
-
|
|
23
|
-
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
|
24
|
-
build/Release
|
|
25
|
-
|
|
26
|
-
# Dependency directory
|
|
27
|
-
node_modules
|
|
28
|
-
|
|
29
|
-
# Optional npm cache directory
|
|
30
|
-
.npm
|
|
31
|
-
|
|
32
|
-
# Optional REPL history
|
|
33
|
-
.node_repl_history
|
|
34
|
-
test
|
|
35
|
-
.travis.yml
|