Comparing version 2.0.1 to 2.1.0
79
docs.md
@@ -1,39 +0,49 @@ | ||
# Fi Errors | ||
# Global | ||
* * * | ||
### buildError(options) | ||
### config(cfg) | ||
Builds an error function. | ||
Initialize and configure the errors component. | ||
**Parameters** | ||
**cfg**: `Object`, The errors configuration object. | ||
**options**: `Object`, The error definition. | ||
- **cfg.errors**: `Array`, The custom errors configuration array file. | ||
- **options.name**: `String`, The error name. | ||
- **cfg.redirect**: `Object`, The default redirect urls. | ||
- **options.message**: `String`, The error default message. | ||
- **cfg.exclude**: `String`, The urls that if failed will terminate the request. | ||
- **options.code**: `String`, The error HTTP response code. | ||
**Returns**: `Object`, The errors component. | ||
**Returns**: `Error`, The created custom error. | ||
### handler(err, req, res, next) | ||
### CustomError(message) | ||
Set proper HTTP status code for custom errors. | ||
Custom Error template. | ||
**Parameters** | ||
**err**: `Error`, The generated error. | ||
**message**: `String`, The error's message. | ||
**req**: `Object`, The request object. | ||
**res**: `Object`, The response object. | ||
**next**: `function`, The following middleware. Must be declared to access error | ||
### register(global, attribute) | ||
Register the custom errors list in the application global object. | ||
**Parameters** | ||
**global**: `Object`, The application global object. | ||
**attribute**: `String`, The name of the attribute to register in the global object. | ||
**Returns**: `Object`, The errors component. | ||
### notFoundMiddleware(req, res, next) | ||
@@ -52,15 +62,44 @@ | ||
### register(global, attribute) | ||
Register the custom errors list in the application global object. | ||
### handler(err, req, res, next) | ||
Set proper HTTP status code for custom errors. | ||
**Parameters** | ||
**global**: `Object`, The application global object. | ||
**err**: `Error`, The generated error. | ||
**attribute**: `String`, The name of the attribute to register in the global object. | ||
**req**: `Object`, The request object. | ||
**res**: `Object`, The response object. | ||
**next**: `function`, The following middleware. Must be declared to access | ||
error. | ||
**Returns**: `undefined` | ||
### config(cfg) | ||
Initialize and configure the errors component. | ||
**Parameters** | ||
**cfg**: `Object`, The errors configuration object. | ||
- **cfg.errors**: `Array`, The custom errors configuration array file. | ||
- **cfg.redirect**: `Object`, The default redirect urls. | ||
- **cfg.exclude**: `String`, The urls that will end the response if failed. | ||
- **cfg.debug**: `function`, The function to use to debug an error. | ||
- **cfg.shouldDebug**: `function`, The function to call to determine if an | ||
error should be debugged. | ||
**Returns**: `Object`, The errors component. | ||
* * * | ||
@@ -76,2 +115,2 @@ | ||
**Version:** 2.0.0 | ||
**Version:** 1.0.0 |
@@ -9,43 +9,37 @@ 'use strict'; | ||
// Common application errors | ||
errors: [ | ||
errors: [{ | ||
name: 'BadRequestError', | ||
message: 'Request malformed.', | ||
code: 400 | ||
}, { | ||
name: 'UnauthorizedError', | ||
message: 'This request requires authentication.', | ||
code: 401 | ||
}, { | ||
name: 'ForbiddenError', | ||
message: 'This request is forbidden.', | ||
code: 403 | ||
}, { | ||
name: 'NotFoundError', | ||
message: 'The requested resource was not found.', | ||
code: 404 | ||
}, { | ||
name: 'ConflictError', | ||
message: 'There is a conflict with another resource with this request.', | ||
code: 409 | ||
}, { | ||
name: 'PreconditionFailedError', | ||
message: 'There is a failed precondition with this request.', | ||
code: 412 | ||
}, { | ||
name: 'ImATeapotError', | ||
message: 'You\'re a teapot.', | ||
code: 418 | ||
}, { | ||
name: 'InternalServerError', | ||
message: 'Something went bad in the server.', | ||
code: 500 | ||
}], | ||
{ | ||
name: 'BadRequestError', | ||
message: 'Request malformed.', | ||
code: 400 | ||
}, | ||
{ | ||
name: 'UnauthorizedError', | ||
message: 'This request requires authentication.', | ||
code: 401 | ||
}, | ||
{ | ||
name: 'ForbiddenError', | ||
message: 'This request is forbidden.', | ||
code: 403 | ||
}, | ||
{ | ||
name: 'NotFoundError', | ||
message: 'The requested route was not found.', | ||
code: 404 | ||
}, | ||
{ | ||
name: 'PreconditionFailedError', | ||
message: 'There is a failed precondition with this request.', | ||
code: 412 | ||
}, | ||
{ | ||
name: 'InternalServerError', | ||
message: 'Something went bad in the server.', | ||
code: 500 | ||
} | ||
], | ||
// Every failed HTTP request to this urls will be terminated | ||
// Every failed HTTP request to this urls will be terminated | ||
exclude: /^\/(assets|api)\//i, | ||
@@ -59,4 +53,8 @@ | ||
globalRegisterName: 'Errors' | ||
// Whether to use console.log, a custom debug method or none | ||
debug: true, | ||
// Condition to debug an error | ||
shouldDebug: err => err.code > 399 | ||
}; |
231
lib/index.js
'use strict'; | ||
const is = require('fi-is'); | ||
/** | ||
@@ -9,4 +11,4 @@ * @module fi-errors | ||
* @license MIT | ||
* | ||
* @overview This component acts as the very last middleware of an express application. It manages every error may be produced inside any of the previous express middlewares. | ||
* | ||
* @overview This component acts as the very last middleware of an express application. It manages every error may be produced inside any of the previous express middlewares. | ||
*/ | ||
@@ -17,9 +19,2 @@ | ||
/* Vars */ | ||
const NOT_FOUND_MIDDLEWARE = 'notFoundMiddleware'; | ||
const REGISTER = 'register'; | ||
const HANDLER = 'handler'; | ||
const CONFIG = 'config'; | ||
const NL = '\n'; | ||
/** | ||
@@ -32,3 +27,3 @@ * The fi-errors component | ||
* Handlers for errors. | ||
* | ||
* | ||
* @type {Object} | ||
@@ -41,3 +36,3 @@ * @private | ||
* Every redirect url. | ||
* | ||
* | ||
* @type {Object} | ||
@@ -49,4 +44,4 @@ * @private | ||
/** | ||
* Every failed HTTP request to this urls will be terminated | ||
* | ||
* Every failed HTTP request to this urls will be terminated | ||
* | ||
* @type {String} | ||
@@ -59,3 +54,3 @@ * @private | ||
* Checks if the component has been configured. | ||
* | ||
* | ||
* @type {Boolean} | ||
@@ -67,5 +62,21 @@ * @private | ||
/** | ||
* Debug function reference; | ||
* @private | ||
*/ | ||
var debug = function () {}; | ||
/** | ||
* Function to determine if the module should debug the error. | ||
* | ||
* @private | ||
* | ||
* @returns {Boolean} Whether to debug. | ||
*/ | ||
var shouldDebug = function () { | ||
return true; | ||
}; | ||
/** | ||
* Builds an error function. | ||
* | ||
* @private | ||
* | ||
* @param {Object} options The error definition. | ||
@@ -75,7 +86,10 @@ * @param {String} options.name The error name. | ||
* @param {String} options.code The error HTTP response code. | ||
* | ||
* @returns {Function} An error function. | ||
* | ||
* @returns {Error} The created custom error. | ||
*/ | ||
function _buildError(options) { | ||
if (!options || !options.name || !options.message || !options.code) { | ||
function buildError(options) { | ||
var isMalformed = is.empty(options) || is.empty(options.name) || | ||
is.empty(options.message) || is.empty(options.code); | ||
if (isMalformed) { | ||
throw new Error('Malformed custom error'); | ||
@@ -85,16 +99,31 @@ } | ||
/** | ||
* Create function dinamically | ||
* Custom Error template. | ||
* | ||
* @param {String} message The error's message. | ||
*/ | ||
var error = function (message) { | ||
this.name = options.name; | ||
this.code = options.code; | ||
this.message = message || options.message; | ||
this.stack = (new Error()).stack; | ||
}; | ||
function CustomError(message) { | ||
Object.defineProperty(this, 'name', { | ||
enumerable: false, | ||
writable: false, | ||
value: options.name || 'CustomError' | ||
}); | ||
// Chain object constructor | ||
error.prototype = Object.create(Error.prototype); | ||
error.prototype.constructor = error; | ||
Object.defineProperty(this, 'code', { | ||
enumerable: false, | ||
writable: true, | ||
value: options.code | ||
}); | ||
return error; | ||
Object.defineProperty(this, 'message', { | ||
enumerable: false, | ||
writable: true, | ||
value: message || options.message | ||
}); | ||
Error.captureStackTrace(this, CustomError); | ||
} | ||
Object.setPrototypeOf(CustomError.prototype, Error.prototype); | ||
return CustomError; | ||
} | ||
@@ -104,8 +133,7 @@ | ||
* Define an error property in the component | ||
* | ||
* | ||
* @param {String} name The error name. | ||
* @param {Function} error The builded error. | ||
* @param {Function} error The builded error. | ||
*/ | ||
function _defineErrorPropety(name, error) { | ||
Object.defineProperty(errors, name, { | ||
@@ -115,3 +143,2 @@ writable: false, | ||
}); | ||
} | ||
@@ -121,5 +148,5 @@ | ||
* Builds each custom error. | ||
* | ||
* | ||
* @private | ||
* @param {Array} _errors An array of custom errors. | ||
* @param {Array} _errors An array of custom errors. | ||
*/ | ||
@@ -130,4 +157,4 @@ function _loadErrors(_errors) { | ||
// First load the errors passed by the user. | ||
_errors.forEach((options) => { | ||
let error = _buildError(options); | ||
_errors.forEach(options => { | ||
let error = buildError(options); | ||
_defineErrorPropety(options.name, error); | ||
@@ -137,18 +164,17 @@ }); | ||
// Then load the default errors if it's not already loaded. | ||
defaults.errors.forEach((options) => { | ||
defaults.errors.forEach(options => { | ||
if (!errors[options.name]) { | ||
let error = _buildError(options); | ||
let error = buildError(options); | ||
_defineErrorPropety(options.name, error); | ||
} | ||
}); | ||
} | ||
/** | ||
* Register the error handlers where the each key may refer to | ||
* Register the error handlers where the each key may refer to | ||
* an error name such as "ValidationError" or an error code as 11000. | ||
* And the value must refer to a registered error name. | ||
* | ||
* | ||
* @private | ||
* @param {Object} _handlers Contains error handlers. | ||
* @param {Object} _handlers Contains error handlers. | ||
*/ | ||
@@ -171,5 +197,5 @@ function _loadHandlers(_handlers) { | ||
* Register the redirection urls. | ||
* | ||
* | ||
* @private | ||
* @param {Object} _redirect Contains the error and lost redirection urls. | ||
* @param {Object} _redirect Contains the error and lost redirection urls. | ||
*/ | ||
@@ -194,3 +220,3 @@ function _loadRedirections(_redirect) { | ||
* Register the excluded routes. | ||
* | ||
* | ||
* @private | ||
@@ -204,7 +230,8 @@ * @param {Regex} _exclude Every failed HTTP request to this urls will be terminated. | ||
/** | ||
* Resolve the error catched by the component handler. | ||
* | ||
* Resolve the error catched by the component handler. | ||
* | ||
* @private | ||
* @param {Object} error The catched error. | ||
* @returns A fi-errors registered error. | ||
* | ||
* @returns {Error} A fi-errors registered error. | ||
*/ | ||
@@ -214,23 +241,19 @@ function _resolveError(error) { | ||
var resolve; | ||
// Its a registered component error. | ||
if (errors[error.name]) { | ||
resolve = error; | ||
return error; | ||
} | ||
// It's registered in the handlers with an error name. | ||
} else if (handlers[error.name]) { | ||
resolve = new handlers[error.name](); | ||
// It's registered in the handlers with an error name. | ||
if (handlers[error.name]) { | ||
return new handlers[error.name](); | ||
} | ||
// It's registered in the handlers with an error code. | ||
} else if (handlers[error.code]) { | ||
resolve = new handlers[error.code](); | ||
// It's not a registered error neither a known error handler. | ||
} else { | ||
resolve = new errors.InternalServerError(); | ||
// It's registered in the handlers with an error code. | ||
if (handlers[error.code]) { | ||
return new handlers[error.code](); | ||
} | ||
return resolve; | ||
// It's not a registered error nor a known error handler. | ||
return new errors.InternalServerError(); | ||
} | ||
@@ -240,6 +263,6 @@ | ||
* Register the custom errors list in the application global object. | ||
* | ||
* | ||
* @param {Object} global The application global object. | ||
* @param {String} attribute The name of the attribute to register in the global object. | ||
* | ||
* | ||
* @returns {Object} The errors component. | ||
@@ -259,4 +282,4 @@ */ | ||
* Catches 404s and forwards them to the error handler. | ||
* | ||
* @param {Object} req The request object. | ||
* | ||
* @param {Object} req The request object. | ||
* @param {Object} res The response object. | ||
@@ -270,8 +293,11 @@ * @param {Function} next The following middleware. | ||
/** | ||
* Set proper HTTP status code for custom errors. | ||
* | ||
* Set proper HTTP status code for custom errors. | ||
* | ||
* @param {Error} err The generated error. | ||
* @param {Object} req The request object. | ||
* @param {Object} req The request object. | ||
* @param {Object} res The response object. | ||
* @param {Function} next The following middleware. Must be declared to access error | ||
* @param {Function} next The following middleware. Must be declared to access | ||
* error. | ||
* | ||
* @returns {undefined} | ||
*/ | ||
@@ -281,18 +307,10 @@ function handler(err, req, res, next) { // eslint-disable-line | ||
// Always log if it's an internal error | ||
if (err.code === new errors.InternalServerError().code) { | ||
console.log(NL); | ||
console.log(new Date()); | ||
console.error(err.stack); | ||
console.log(NL); | ||
if (shouldDebug(err)) { | ||
debug(err); | ||
} | ||
// Always assign the error code to the response status | ||
/* Always assign the error code to the response status */ | ||
res.status(err.code); | ||
/** | ||
* If the request is an AJAX call or is for an asset or API method | ||
* just end the response | ||
* | ||
*/ | ||
/* If the request is AJAX or matches an excluded path just end the response */ | ||
if (req.xhr || exclude.test(req.path)) { | ||
@@ -302,3 +320,3 @@ return res.end(); | ||
/* If it's a 404 render the lost page */ | ||
/* Render the lost page if it's a 404 error */ | ||
if (err.code === new errors.NotFoundError().code) { | ||
@@ -308,2 +326,3 @@ return res.redirect(redirect.lost + encodeURIComponent(req.originalUrl)); | ||
/* Redirect to error page */ | ||
res.redirect(redirect.error); | ||
@@ -314,8 +333,11 @@ } | ||
* Initialize and configure the errors component. | ||
* | ||
* | ||
* @param {Object} cfg The errors configuration object. | ||
* @param {Array} cfg.errors The custom errors configuration array file. | ||
* @param {Object} cfg.redirect The default redirect urls. | ||
* @param {String} cfg.exclude The urls that if failed will terminate the request. | ||
* | ||
* @param {String} cfg.exclude The urls that will end the response if failed. | ||
* @param {Function} cfg.debug The function to use to debug an error. | ||
* @param {Function} cfg.shouldDebug The function to call to determine if an | ||
* error should be debugged. | ||
* | ||
* @returns {Object} The errors component. | ||
@@ -331,2 +353,14 @@ */ | ||
/* Set debug method */ | ||
if (is.function(cfg.debug)) { | ||
debug = cfg.debug; | ||
} else if (is.boolean(debug)) { | ||
debug = console.log.bind(console); | ||
} | ||
/* Set should debug method */ | ||
if (is.function(cfg.shouldDebug)) { | ||
shouldDebug = cfg.shouldDebug; | ||
} | ||
initialized = true; | ||
@@ -338,3 +372,3 @@ | ||
/* Define component config function */ | ||
Object.defineProperty(errors, CONFIG, { | ||
Object.defineProperty(errors, 'config', { | ||
writable: false, | ||
@@ -346,3 +380,3 @@ enumerable: false, | ||
/* Define component register function */ | ||
Object.defineProperty(errors, REGISTER, { | ||
Object.defineProperty(errors, 'register', { | ||
writable: false, | ||
@@ -354,3 +388,3 @@ enumerable: false, | ||
/* Define component handler */ | ||
Object.defineProperty(errors, HANDLER, { | ||
Object.defineProperty(errors, 'handler', { | ||
writable: false, | ||
@@ -362,6 +396,13 @@ enumerable: false, | ||
/* Define component not found middleware */ | ||
Object.defineProperty(errors, NOT_FOUND_MIDDLEWARE, { | ||
Object.defineProperty(errors, 'notFoundMiddleware', { | ||
writable: false, | ||
enumerable: false, | ||
value: notFoundMiddleware | ||
}); | ||
}); | ||
/* Define build error export */ | ||
Object.defineProperty(errors, 'buildError', { | ||
writable: false, | ||
enumerable: false, | ||
value: buildError | ||
}); |
{ | ||
"name": "fi-errors", | ||
"title": "Fi Errors", | ||
"version": "2.0.1", | ||
"version": "2.1.0", | ||
"description": "Error manangement middleware for ExpressJS", | ||
@@ -10,2 +10,3 @@ "main": "index.js", | ||
"scripts": { | ||
"docs": "rm docs.md && jsdox ./lib/index.js -o ./ && mv index.md docs.md", | ||
"test": "node test/index" | ||
@@ -39,3 +40,6 @@ }, | ||
"request": "^2.81.0" | ||
}, | ||
"dependencies": { | ||
"fi-is": "^1.2.0" | ||
} | ||
} |
@@ -27,16 +27,14 @@ # Fi Errors | ||
{ | ||
name: 'myCustomError', | ||
message: 'My custom error default message' | ||
code: 418 | ||
name: 'EnhanceYourCalmError', | ||
message: 'Breath in... Breath out...' | ||
code: 420 | ||
}, | ||
// This error will overwrite the default BadRequestError | ||
// This errors will overwrite the default errors with new messages | ||
{ | ||
name: 'BadRequestError', | ||
message: 'The request could not be understood by the server due to malformed syntax' | ||
message: 'The request could not be understood by the server due to malformed syntax.' | ||
code: 400 | ||
}, | ||
{ | ||
name: 'DuplicatedEntityError', | ||
}, { | ||
name: 'ConflictError', | ||
message: 'This document is already registered.', | ||
@@ -63,3 +61,14 @@ code: 409 | ||
lost: '/lost?url=' | ||
} | ||
}, | ||
// Function to use for debugging | ||
debug: err => { | ||
console.log('START ERROR LOG:', new Date()); | ||
console.log(err); | ||
console.log('END ERROR LOG:', new Date()); | ||
}, | ||
// Condition to debug an error | ||
shouldDebug: err => err.code > 399 | ||
}; | ||
@@ -66,0 +75,0 @@ ``` |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
17704
373
137
0
1
+ Addedfi-is@^1.2.0
+ Addedfi-is@1.3.1(transitive)