strong-error-handler 3.1.0 → 3.5.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 CHANGED
@@ -1,4 +1,42 @@
1
- 2018-07-17, Version 3.1.0
1
+ 2020-06-23, Version 3.5.0
2
+ =========================
3
+
4
+ * feat: add options.rootProperty for json/xml (Raymond Feng)
5
+
6
+ * chore: update deps and drop Node 8.x support (Raymond Feng)
7
+
8
+
9
+ 2019-10-12, Version 3.4.0
10
+ =========================
11
+
12
+ * chore: js2xmlparser to ^4.0.0 (Miroslav Bajtoš)
13
+
14
+ * chore: update dev-dependencies (mocha, supertest) (Miroslav Bajtoš)
15
+
16
+ * chore: update eslint & config to latest (Miroslav Bajtoš)
17
+
18
+ * chore: update strong-globalize to ^5.0.2 (Miroslav Bajtoš)
19
+
20
+ * chore: update debug to ^4.1.1 (Miroslav Bajtoš)
21
+
22
+ * feat: drop support for Node.js 6.x (Miroslav Bajtoš)
23
+
24
+
25
+ 2019-09-30, Version 3.3.0
26
+ =========================
27
+
28
+ * fix: handle Error objects with circular properties (dkrantsberg)
29
+
30
+ * chore: update copyrights years (Agnes Lin)
31
+
32
+
33
+ 2018-08-30, Version 3.2.0
34
+ =========================
35
+
36
+ * Add type definition and writeErrorToResponse (shimks)
37
+
38
+
39
+ 2018-07-16, Version 3.1.0
2
40
  =========================
3
41
 
4
42
  * [WebFM] cs/pl/ru translation (candytangnb)
package/README.md CHANGED
@@ -14,9 +14,9 @@ In debug mode, `strong-error-handler` returns full error stack traces and intern
14
14
 
15
15
  ## Supported versions
16
16
 
17
- Current|Long Term Support|Maintenance
18
- :-:|:-:|:-:
19
- 3.x|2.x|1.x
17
+ | Current | Long Term Support | Maintenance |
18
+ | :-----: | :---------------: | :---------: |
19
+ | 4.x | 3.x | 2.x |
20
20
 
21
21
  Learn more about our LTS plan in [docs](http://loopback.io/doc/en/contrib/Long-term-support.html).
22
22
 
@@ -46,6 +46,29 @@ app.use(errorHandler({
46
46
  app.listen(3000);
47
47
  ```
48
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
+
49
72
  In LoopBack applications, add the following entry to `server/middleware.json`:
50
73
 
51
74
  ```json
@@ -85,24 +108,25 @@ The content type of the response depends on the request's `Accepts` header.
85
108
 
86
109
  ## Options
87
110
 
88
- | Option | Type | Default | Description |
89
- | ---- | ---- | ---- | ---- |
90
- | 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. |
91
- | 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. |
92
- | 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. |
93
- | defaultType | String | `"json"` | Specify the default response content type to use when the client does not provide any Accepts header.
94
- | 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.
111
+ | Option | Type | Default | Description |
112
+ | -------------------- | ------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
113
+ | debug | Boolean&nbsp;&nbsp;&nbsp; | `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. |
114
+ | 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. |
115
+ | 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. |
116
+ | defaultType | String | `"json"` | Specifies the default response content type to use when the client does not provide any Accepts header. |
117
+ | rootProperty | String or false | `"error"` | Specifies the root property name for json or xml. If the value is set to `false`, no wrapper will be added to the json object. The false value is ignored by XML as a root element is always required. |
118
+ | 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. |
95
119
 
96
120
  ### Customizing log format
97
121
 
98
- **Express**
122
+ **Express**
99
123
 
100
- To use a different log format, add your own custom error-handling middleware then disable `errorHandler.log`.
124
+ To use a different log format, add your own custom error-handling middleware then disable `errorHandler.log`.
101
125
  For example, in an Express application:
102
126
 
103
127
  ```js
104
128
  app.use(myErrorLogger());
105
- app.use(errorHandler({ log: false }));
129
+ app.use(errorHandler({log: false}));
106
130
  ```
107
131
 
108
132
  In general, add `strong-error-handler` as the last middleware function, just before calling `app.listen()`.
@@ -211,7 +235,7 @@ To migrate a LoopBack 2.x application to use `strong-error-handler`:
211
235
  }
212
236
  </pre>
213
237
 
214
- For more information, see
238
+ For more information, see
215
239
  [Migrating apps to LoopBack 3.0](http://loopback.io/doc/en/lb3/Migrating-to-3.0.html#update-use-of-rest-error-handler).
216
240
 
217
241
  ## Example
@@ -229,17 +253,17 @@ The same error generated when `debug: true` :
229
253
  { statusCode: 500,
230
254
  name: 'Error',
231
255
  message: 'a test error message',
232
- stack: 'Error: a test error message
233
- at Context.<anonymous> (User/strong-error-handler/test/handler.test.js:220:21)
234
- at callFnAsync (User/strong-error-handler/node_modules/mocha/lib/runnable.js:349:8)
235
- at Test.Runnable.run (User/strong-error-handler/node_modules/mocha/lib/runnable.js:301:7)
236
- at Runner.runTest (User/strong-error-handler/node_modules/mocha/lib/runner.js:422:10)
237
- at User/strong-error-handler/node_modules/mocha/lib/runner.js:528:12
238
- at next (User/strong-error-handler/node_modules/mocha/lib/runner.js:342:14)
239
- at User/strong-error-handler/node_modules/mocha/lib/runner.js:352:7
240
- at next (User/strong-error-handler/node_modules/mocha/lib/runner.js:284:14)
241
- at Immediate._onImmediate (User/strong-error-handler/node_modules/mocha/lib/runner.js:320:5)
242
- at tryOnImmediate (timers.js:543:15)
256
+ stack: 'Error: a test error message
257
+ at Context.<anonymous> (User/strong-error-handler/test/handler.test.js:220:21)
258
+ at callFnAsync (User/strong-error-handler/node_modules/mocha/lib/runnable.js:349:8)
259
+ at Test.Runnable.run (User/strong-error-handler/node_modules/mocha/lib/runnable.js:301:7)
260
+ at Runner.runTest (User/strong-error-handler/node_modules/mocha/lib/runner.js:422:10)
261
+ at User/strong-error-handler/node_modules/mocha/lib/runner.js:528:12
262
+ at next (User/strong-error-handler/node_modules/mocha/lib/runner.js:342:14)
263
+ at User/strong-error-handler/node_modules/mocha/lib/runner.js:352:7
264
+ at next (User/strong-error-handler/node_modules/mocha/lib/runner.js:284:14)
265
+ at Immediate._onImmediate (User/strong-error-handler/node_modules/mocha/lib/runner.js:320:5)
266
+ at tryOnImmediate (timers.js:543:15)
243
267
  at processImmediate [as _immediateCallback] (timers.js:523:5)' }}
244
268
  ```
245
269
 
package/index.d.ts ADDED
@@ -0,0 +1,65 @@
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
+ rootProperty?: string | false;
57
+ }
58
+
59
+ /**
60
+ * Options for error-handling
61
+ */
62
+ interface ErrorHandlerOptions extends ErrorWriterOptions {
63
+ log?: boolean;
64
+ }
65
+ }
package/lib/clone.js CHANGED
@@ -1,3 +1,8 @@
1
+ // Copyright IBM Corp. 2016. 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
+
1
6
  'use strict';
2
7
  module.exports = cloneAllProperties;
3
8
 
@@ -10,10 +15,10 @@ module.exports = cloneAllProperties;
10
15
  function cloneAllProperties(data, err) {
11
16
  data.name = err.name;
12
17
  data.message = err.message;
13
- for (var p in err) {
18
+ for (const p in err) {
14
19
  if ((p in data)) continue;
15
20
  data[p] = err[p];
16
21
  }
17
22
  // stack is appended last to ensure order is the same for response
18
23
  data.stack = err.stack;
19
- };
24
+ }
@@ -1,15 +1,15 @@
1
- // Copyright IBM Corp. 2016. All Rights Reserved.
1
+ // Copyright IBM Corp. 2016,2018. All Rights Reserved.
2
2
  // Node module: strong-error-handler
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
6
  'use strict';
7
- var accepts = require('accepts');
8
- var debug = require('debug')('strong-error-handler:http-response');
9
- var sendJson = require('./send-json');
10
- var sendHtml = require('./send-html');
11
- var sendXml = require('./send-xml');
12
- var util = require('util');
7
+ const accepts = require('accepts');
8
+ const debug = require('debug')('strong-error-handler:http-response');
9
+ const sendJson = require('./send-json');
10
+ const sendHtml = require('./send-html');
11
+ const sendXml = require('./send-xml');
12
+ const util = require('util');
13
13
 
14
14
  module.exports = negotiateContentProducer;
15
15
 
@@ -23,14 +23,14 @@ module.exports = negotiateContentProducer;
23
23
  * @returns {Function} Operation function with signature `fn(res, data)`
24
24
  */
25
25
  function negotiateContentProducer(req, logWarning, options) {
26
- var SUPPORTED_TYPES = [
26
+ const SUPPORTED_TYPES = [
27
27
  'application/json', 'json',
28
28
  'text/html', 'html',
29
29
  'text/xml', 'xml',
30
30
  ];
31
31
 
32
32
  options = options || {};
33
- var defaultType = 'json';
33
+ let defaultType = 'json';
34
34
 
35
35
  // checking if user provided defaultType is supported
36
36
  if (options.defaultType) {
@@ -52,9 +52,9 @@ function negotiateContentProducer(req, logWarning, options) {
52
52
  // Accepts: */*, application/json, text/html ---> will resolve as application/json
53
53
  // eg. Chrome accepts defaults to `text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*`
54
54
  // In this case `resolvedContentType` will result as: `text/html` due to the order given
55
- var resolvedContentType = accepts(req).types(SUPPORTED_TYPES);
55
+ const resolvedContentType = accepts(req).types(SUPPORTED_TYPES);
56
56
  debug('Resolved content-type', resolvedContentType);
57
- var contentType = resolvedContentType || defaultType;
57
+ let contentType = resolvedContentType || defaultType;
58
58
 
59
59
  if (options.negotiateContentType === false) {
60
60
  if (SUPPORTED_TYPES.indexOf(options.defaultType) > -1) {
@@ -71,13 +71,13 @@ function negotiateContentProducer(req, logWarning, options) {
71
71
  // to receive _format from user's url param to overide the content type
72
72
  // req.query (eg /api/Users/1?_format=json will overide content negotiation
73
73
  // https://github.com/strongloop/strong-remoting/blob/ac3093dcfbb787977ca0229b0f672703859e52e1/lib/http-context.js#L643-L645
74
- var query = req.query || {};
74
+ const query = req.query || {};
75
75
  if (query._format) {
76
76
  if (SUPPORTED_TYPES.indexOf(query._format) > -1) {
77
77
  contentType = query._format;
78
78
  } else {
79
79
  // format passed through query but not supported
80
- var msg = util.format('Response _format "%s" is not supported' +
80
+ const msg = util.format('Response _format "%s" is not supported' +
81
81
  'used "%s" instead"', query._format, defaultType);
82
82
  logWarning(msg);
83
83
  }
@@ -1,12 +1,12 @@
1
- // Copyright IBM Corp. 2016. All Rights Reserved.
1
+ // Copyright IBM Corp. 2016,2018. All Rights Reserved.
2
2
  // Node module: strong-error-handler
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
6
  'use strict';
7
7
 
8
- var cloneAllProperties = require('../lib/clone.js');
9
- var httpStatus = require('http-status');
8
+ const cloneAllProperties = require('../lib/clone.js');
9
+ const httpStatus = require('http-status');
10
10
 
11
11
  module.exports = buildResponseData;
12
12
 
@@ -44,7 +44,7 @@ function buildResponseData(err, options) {
44
44
  fillSafeFields(data, err, safeFields);
45
45
 
46
46
  return data;
47
- };
47
+ }
48
48
 
49
49
  function serializeArrayOfErrors(errors, options) {
50
50
  const details = errors.map(e => buildResponseData(e, options));
package/lib/handler.js CHANGED
@@ -1,18 +1,17 @@
1
- // Copyright IBM Corp. 2016. All Rights Reserved.
1
+ // Copyright IBM Corp. 2016,2018. All Rights Reserved.
2
2
  // Node module: strong-error-handler
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
6
  'use strict';
7
7
 
8
- var path = require('path');
9
- var SG = require('strong-globalize');
8
+ const path = require('path');
9
+ const SG = require('strong-globalize');
10
10
  SG.SetRootDir(path.resolve(__dirname, '..'));
11
- var buildResponseData = require('./data-builder');
12
- var debug = require('debug')('strong-error-handler');
13
- var format = require('util').format;
14
- var logToConsole = require('./logger');
15
- var negotiateContentProducer = require('./content-negotiation');
11
+ const buildResponseData = require('./data-builder');
12
+ const debug = require('debug')('strong-error-handler');
13
+ const logToConsole = require('./logger');
14
+ const negotiateContentProducer = require('./content-negotiation');
16
15
 
17
16
  function noop() {
18
17
  }
@@ -23,40 +22,56 @@ function noop() {
23
22
  * @param {Object} options
24
23
  * @returns {Function}
25
24
  */
26
- exports = module.exports = function createStrongErrorHandler(options) {
25
+ function createStrongErrorHandler(options) {
27
26
  options = options || {};
28
27
 
29
28
  debug('Initializing with options %j', options);
30
29
 
31
30
  // Log all errors via console.error (enabled by default)
32
- var logError = options.log !== false ? logToConsole : noop;
31
+ const logError = options.log !== false ? logToConsole : noop;
33
32
 
34
33
  return function strongErrorHandler(err, req, res, next) {
35
- debug('Handling %s', err.stack || err);
36
-
37
34
  logError(req, err);
35
+ writeErrorToResponse(err, req, res, options);
36
+ };
37
+ }
38
38
 
39
- if (res._header) {
40
- debug('Response was already sent, closing the underlying connection');
41
- return req.socket.destroy();
42
- }
39
+ /**
40
+ * Writes thrown error to response
41
+ *
42
+ * @param {Error} err
43
+ * @param {Express.Request} req
44
+ * @param {Express.Response} res
45
+ * @param {Object} options
46
+ */
47
+ function writeErrorToResponse(err, req, res, options) {
48
+ debug('Handling %s', err.stack || err);
43
49
 
44
- // this will alter the err object, to handle when res.statusCode is an error
45
- if (!err.status && !err.statusCode && res.statusCode >= 400)
46
- err.statusCode = res.statusCode;
50
+ options = options || {};
47
51
 
48
- var data = buildResponseData(err, options);
49
- debug('Response status %s data %j', data.statusCode, data);
52
+ if (res.headersSent) {
53
+ debug('Response was already sent, closing the underlying connection');
54
+ return req.socket.destroy();
55
+ }
50
56
 
51
- res.setHeader('X-Content-Type-Options', 'nosniff');
52
- res.statusCode = data.statusCode;
57
+ // this will alter the err object, to handle when res.statusCode is an error
58
+ if (!err.status && !err.statusCode && res.statusCode >= 400)
59
+ err.statusCode = res.statusCode;
53
60
 
54
- var sendResponse = negotiateContentProducer(req, warn, options);
55
- sendResponse(res, data);
61
+ const data = buildResponseData(err, options);
62
+ debug('Response status %s data %j', data.statusCode, data);
56
63
 
57
- function warn(msg) {
58
- res.header('X-Warning', msg);
59
- debug(msg);
60
- }
61
- };
62
- };
64
+ res.setHeader('X-Content-Type-Options', 'nosniff');
65
+ res.statusCode = data.statusCode;
66
+
67
+ const sendResponse = negotiateContentProducer(req, warn, options);
68
+ sendResponse(res, data, options);
69
+
70
+ function warn(msg) {
71
+ res.header('X-Warning', msg);
72
+ debug(msg);
73
+ }
74
+ }
75
+
76
+ exports = module.exports = createStrongErrorHandler;
77
+ exports.writeErrorToResponse = writeErrorToResponse;
package/lib/logger.js CHANGED
@@ -5,8 +5,8 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- var format = require('util').format;
9
- var g = require('strong-globalize')();
8
+ const format = require('util').format;
9
+ const g = require('strong-globalize')();
10
10
 
11
11
  module.exports = function logToConsole(req, err) {
12
12
  if (!Array.isArray(err)) {
@@ -15,9 +15,9 @@ module.exports = function logToConsole(req, err) {
15
15
  return;
16
16
  }
17
17
 
18
- var errMsg = g.f('Unhandled array of errors for request %s %s\n',
18
+ const errMsg = g.f('Unhandled array of errors for request %s %s\n',
19
19
  req.method, req.url);
20
- var errors = err.map(formatError).join('\n');
20
+ const errors = err.map(formatError).join('\n');
21
21
  console.error(errMsg, errors);
22
22
  };
23
23
 
package/lib/send-html.js CHANGED
@@ -4,12 +4,12 @@
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
6
  'use strict';
7
- var ejs = require('ejs');
8
- var fs = require('fs');
9
- var path = require('path');
7
+ const ejs = require('ejs');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
10
 
11
- var assetDir = path.resolve(__dirname, '../views');
12
- var compiledTemplates = {
11
+ const assetDir = path.resolve(__dirname, '../views');
12
+ const compiledTemplates = {
13
13
  // loading default template and stylesheet
14
14
  default: loadDefaultTemplates(),
15
15
  };
@@ -17,10 +17,10 @@ var compiledTemplates = {
17
17
  module.exports = sendHtml;
18
18
 
19
19
  function sendHtml(res, data, options) {
20
- var toRender = {options: {}, data: data};
20
+ const toRender = {options, data};
21
21
  // TODO: ability to call non-default template functions from options
22
- var body = compiledTemplates.default(toRender);
23
- sendReponse(res, body);
22
+ const body = compiledTemplates.default(toRender);
23
+ sendResponse(res, body);
24
24
  }
25
25
 
26
26
  /**
@@ -30,18 +30,18 @@ function sendHtml(res, data, options) {
30
30
  * @returns {Function} render function with signature fn(data);
31
31
  */
32
32
  function compileTemplate(filepath) {
33
- var options = {cache: true, filename: filepath};
34
- var fileContent = fs.readFileSync(filepath, 'utf8');
33
+ const options = {cache: true, filename: filepath};
34
+ const fileContent = fs.readFileSync(filepath, 'utf8');
35
35
  return ejs.compile(fileContent, options);
36
36
  }
37
37
 
38
38
  // loads and cache default error templates
39
39
  function loadDefaultTemplates() {
40
- var defaultTemplate = path.resolve(assetDir, 'default-error.ejs');
40
+ const defaultTemplate = path.resolve(assetDir, 'default-error.ejs');
41
41
  return compileTemplate(defaultTemplate);
42
42
  }
43
43
 
44
- function sendReponse(res, body) {
44
+ function sendResponse(res, body) {
45
45
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
46
46
  res.end(body);
47
47
  }
package/lib/send-json.js CHANGED
@@ -5,8 +5,16 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- module.exports = function sendJson(res, data) {
9
- var content = JSON.stringify({error: data});
8
+ const safeStringify = require('fast-safe-stringify');
9
+
10
+ module.exports = function sendJson(res, data, options) {
11
+ options = options || {};
12
+ // Set `options.rootProperty` to not wrap the data into an `error` object
13
+ const err = options.rootProperty === false ? data : {
14
+ // Use `options.rootProperty`, if not set, default to `error`
15
+ [options.rootProperty || 'error']: data,
16
+ };
17
+ const content = safeStringify(err);
10
18
  res.setHeader('Content-Type', 'application/json; charset=utf-8');
11
19
  res.end(content, 'utf-8');
12
20
  };
package/lib/send-xml.js CHANGED
@@ -1,14 +1,18 @@
1
- // Copyright IBM Corp. 2016. All Rights Reserved.
1
+ // Copyright IBM Corp. 2017. All Rights Reserved.
2
2
  // Node module: strong-error-handler
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
6
  'use strict';
7
7
 
8
- var js2xmlparser = require('js2xmlparser');
8
+ const js2xmlparser = require('js2xmlparser');
9
9
 
10
- module.exports = function sendXml(res, data) {
11
- var content = js2xmlparser.parse('error', data);
10
+ module.exports = function sendXml(res, data, options) {
11
+ options = options || {};
12
+ // Xml always requires a root element.
13
+ // `options.rootProperty === false` is not honored
14
+ const root = options.rootProperty || 'error';
15
+ const content = js2xmlparser.parse(root, data);
12
16
  res.setHeader('Content-Type', 'text/xml; charset=utf-8');
13
17
  res.end(content, 'utf-8');
14
18
  };
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": "3.1.0",
5
+ "version": "3.5.0",
6
6
  "engines": {
7
- "node": ">=6"
7
+ "node": ">=10"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
@@ -17,20 +17,22 @@
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": "^3.1.0",
22
- "ejs": "^2.6.1",
22
+ "debug": "^4.1.1",
23
+ "ejs": "^3.1.3",
24
+ "fast-safe-stringify": "^2.0.6",
23
25
  "http-status": "^1.1.2",
24
- "js2xmlparser": "^3.0.0",
25
- "strong-globalize": "^4.1.0"
26
+ "js2xmlparser": "^4.0.0",
27
+ "strong-globalize": "^6.0.1"
26
28
  },
27
29
  "devDependencies": {
28
30
  "chai": "^4.1.2",
29
- "eslint": "^4.19.1",
30
- "eslint-config-loopback": "^10.0.0",
31
+ "eslint": "^7.0.0",
32
+ "eslint-config-loopback": "^13.1.0",
31
33
  "express": "^4.16.3",
32
- "mocha": "^5.2.0",
33
- "supertest": "^3.1.0"
34
+ "mocha": "^7.1.2",
35
+ "supertest": "^4.0.2"
34
36
  },
35
37
  "browser": {
36
38
  "strong-error-handler": false
@@ -39,5 +41,6 @@
39
41
  "downstreamIgnoreList": [
40
42
  "dashboard-controller"
41
43
  ]
42
- }
44
+ },
45
+ "author": "IBM Corp."
43
46
  }
@@ -2,7 +2,7 @@
2
2
  <head>
3
3
  <meta charset='utf-8'>
4
4
  <title><%= data.name || data.message %></title>
5
- <style><%- include style.css %></style>
5
+ <style><%- include('style.css') %></style>
6
6
  </head>
7
7
  <body>
8
8
  <div id="wrapper">
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