strong-error-handler 3.0.0 → 3.4.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/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ sudo: false
2
+ language: node_js
3
+ node_js:
4
+ - "8"
5
+ - "10"
6
+ - "12"
package/CHANGES.md CHANGED
@@ -1,4 +1,40 @@
1
- 2018-06-12, Version 3.0.0
1
+ 2019-10-12, Version 3.4.0
2
+ =========================
3
+
4
+ * chore: js2xmlparser to ^4.0.0 (Miroslav Bajtoš)
5
+
6
+ * chore: update dev-dependencies (mocha, supertest) (Miroslav Bajtoš)
7
+
8
+ * chore: update eslint & config to latest (Miroslav Bajtoš)
9
+
10
+ * chore: update strong-globalize to ^5.0.2 (Miroslav Bajtoš)
11
+
12
+ * chore: update debug to ^4.1.1 (Miroslav Bajtoš)
13
+
14
+ * feat: drop support for Node.js 6.x (Miroslav Bajtoš)
15
+
16
+
17
+ 2019-09-30, Version 3.3.0
18
+ =========================
19
+
20
+ * fix: handle Error objects with circular properties (dkrantsberg)
21
+
22
+ * chore: update copyrights years (Agnes Lin)
23
+
24
+
25
+ 2018-08-30, Version 3.2.0
26
+ =========================
27
+
28
+ * Add type definition and writeErrorToResponse (shimks)
29
+
30
+
31
+ 2018-07-16, Version 3.1.0
32
+ =========================
33
+
34
+ * [WebFM] cs/pl/ru translation (candytangnb)
35
+
36
+
37
+ 2018-06-11, Version 3.0.0
2
38
  =========================
3
39
 
4
40
  * Allow safeFields to work with arrays (shimks)
package/README.md CHANGED
@@ -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
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
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "85312d2b987e2e44001db3d6963a1364": "Neošetřené pole chyb pro požadavek {0} {1}\n",
3
+ "adcbd4c562b19f45fb5d3427619646d5": "Neošetřená chyba pro požadavek {0} {1}: {2}"
4
+ }
5
+
@@ -0,0 +1,5 @@
1
+ {
2
+ "85312d2b987e2e44001db3d6963a1364": "Nieobsługiwana tablica błędów dla żądania {0} {1}\n",
3
+ "adcbd4c562b19f45fb5d3427619646d5": "Nieobsługiwany błąd dla żądania {0} {1}: {2}"
4
+ }
5
+
@@ -0,0 +1,5 @@
1
+ {
2
+ "85312d2b987e2e44001db3d6963a1364": "Необработанный массив ошибок для запроса {0} {1}\n",
3
+ "adcbd4c562b19f45fb5d3427619646d5": "Необработанная ошибка для запроса {0} {1}: {2}"
4
+ }
5
+
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,18 @@
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 format = require('util').format;
14
+ const logToConsole = require('./logger');
15
+ const negotiateContentProducer = require('./content-negotiation');
16
16
 
17
17
  function noop() {
18
18
  }
@@ -23,40 +23,56 @@ function noop() {
23
23
  * @param {Object} options
24
24
  * @returns {Function}
25
25
  */
26
- exports = module.exports = function createStrongErrorHandler(options) {
26
+ function createStrongErrorHandler(options) {
27
27
  options = options || {};
28
28
 
29
29
  debug('Initializing with options %j', options);
30
30
 
31
31
  // Log all errors via console.error (enabled by default)
32
- var logError = options.log !== false ? logToConsole : noop;
32
+ const 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
+ }
38
39
 
39
- if (res._header) {
40
- debug('Response was already sent, closing the underlying connection');
41
- return req.socket.destroy();
42
- }
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);
43
50
 
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;
51
+ options = options || {};
47
52
 
48
- var data = buildResponseData(err, options);
49
- debug('Response status %s data %j', data.statusCode, data);
53
+ if (res._header) {
54
+ debug('Response was already sent, closing the underlying connection');
55
+ return req.socket.destroy();
56
+ }
50
57
 
51
- res.setHeader('X-Content-Type-Options', 'nosniff');
52
- res.statusCode = data.statusCode;
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;
53
61
 
54
- var sendResponse = negotiateContentProducer(req, warn, options);
55
- sendResponse(res, data);
62
+ const data = buildResponseData(err, options);
63
+ debug('Response status %s data %j', data.statusCode, data);
56
64
 
57
- function warn(msg) {
58
- res.header('X-Warning', msg);
59
- debug(msg);
60
- }
61
- };
62
- };
65
+ res.setHeader('X-Content-Type-Options', 'nosniff');
66
+ res.statusCode = data.statusCode;
67
+
68
+ const sendResponse = negotiateContentProducer(req, warn, options);
69
+ sendResponse(res, data);
70
+
71
+ function warn(msg) {
72
+ res.header('X-Warning', msg);
73
+ debug(msg);
74
+ }
75
+ }
76
+
77
+ exports = module.exports = createStrongErrorHandler;
78
+ 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,9 +17,9 @@ 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: data};
21
21
  // TODO: ability to call non-default template functions from options
22
- var body = compiledTemplates.default(toRender);
22
+ const body = compiledTemplates.default(toRender);
23
23
  sendReponse(res, body);
24
24
  }
25
25
 
@@ -30,14 +30,14 @@ 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
 
package/lib/send-json.js CHANGED
@@ -5,8 +5,10 @@
5
5
 
6
6
  'use strict';
7
7
 
8
+ const safeStringify = require('fast-safe-stringify');
9
+
8
10
  module.exports = function sendJson(res, data) {
9
- var content = JSON.stringify({error: data});
11
+ const content = safeStringify({error: data});
10
12
  res.setHeader('Content-Type', 'application/json; charset=utf-8');
11
13
  res.end(content, 'utf-8');
12
14
  };
package/lib/send-xml.js CHANGED
@@ -1,14 +1,14 @@
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
10
  module.exports = function sendXml(res, data) {
11
- var content = js2xmlparser.parse('error', data);
11
+ const content = js2xmlparser.parse('error', data);
12
12
  res.setHeader('Content-Type', 'text/xml; charset=utf-8');
13
13
  res.end(content, 'utf-8');
14
14
  };
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.0.0",
5
+ "version": "3.4.0",
6
6
  "engines": {
7
- "node": ">=6"
7
+ "node": ">=8"
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
+ "debug": "^4.1.1",
22
23
  "ejs": "^2.6.1",
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": "^5.0.2"
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": "^6.5.1",
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": "^6.2.1",
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
  }