common-errors
Advanced tools
Comparing version
82
index.js
@@ -0,39 +1,61 @@ | ||
var util = require('util'); | ||
var classGenerator = require('./lib/helpers/class-generator'); | ||
module.exports = { | ||
Validation: require('./lib/validation'), | ||
Generic: require('./lib/generic'), | ||
HttpStatus: require('./lib/http-status'), | ||
NotSupported: require('./lib/not-supported'), | ||
Argument: require('./lib/argument'), | ||
ArgumentNull: require('./lib/argumentNull'), | ||
AlreadyInUse: require('./lib/alreadyInUse'), | ||
NotPermitted: require('./lib/notPermitted'), | ||
AuthenticationRequired: require('./lib/authenticationRequired'), | ||
middleware: { | ||
errorHandler: require('./lib/middleware/errorHandler'), | ||
crashProtector: require('./lib/middleware/crashProtector') | ||
} | ||
Error: classGenerator('Error'), | ||
ReferenceError: classGenerator('ReferenceError', {subclass: ReferenceError}), | ||
Validation: require('./lib/validation'), | ||
Generic: require('./lib/generic'), | ||
HttpStatus: require('./lib/http-status'), | ||
NotSupported: require('./lib/not-supported'), | ||
Argument: require('./lib/argument'), | ||
ArgumentNull: require('./lib/argumentNull'), | ||
AlreadyInUse: require('./lib/alreadyInUse'), | ||
NotPermitted: require('./lib/notPermitted'), | ||
AuthenticationRequired: require('./lib/authenticationRequired'), | ||
helpers: { | ||
generateClass: classGenerator | ||
}, | ||
middleware: { | ||
errorHandler: require('./lib/middleware/errorHandler'), | ||
crashProtector: require('./lib/middleware/crashProtector') | ||
} | ||
}; | ||
var logErrorDeprecationWarning = false; | ||
module.exports.logError = function(err, cb) { | ||
if(!logErrorDeprecationWarning) console.warn("logError is deprecated. Use log instead."); | ||
logErrorDeprecationWarning = true; | ||
module.exports.logError = function(err, cb) { | ||
if (!logErrorDeprecationWarning) console.warn("logError is deprecated. Use log instead."); | ||
logErrorDeprecationWarning = true; | ||
if(err && !err.isLogged) { | ||
err.isLogged = true; | ||
console.error(err); | ||
} | ||
if(cb) cb(err); | ||
if (err && !err.isLogged) { | ||
err.isLogged = true; | ||
console.error(err); | ||
} | ||
if (cb) cb(err); | ||
}; | ||
module.exports.log = function(err, message) { | ||
if(typeof err == 'string') message = err, err = new module.exports.Generic(message); | ||
else if(err && !(err instanceof module.exports.Generic) || err.isLogged) { | ||
err = new module.exports.Generic(message || "A generic error has occurred.", err); | ||
} | ||
if(err) { | ||
console.error(err && err.stack || err); | ||
err.isLogged = true; | ||
} | ||
return err; | ||
if (typeof err == 'string') { | ||
err = new module.exports.Generic(err); | ||
} else { | ||
if (message) { | ||
err.message = message; | ||
} | ||
err = module.exports._prependCurrentStack(err); | ||
} | ||
if (err) { | ||
console.error(err && err.stack || err); | ||
err.isLogged = true; | ||
} | ||
return err; | ||
} | ||
module.exports._prependCurrentStack = function(err) { | ||
// skip the first three lines, because they're just noise | ||
var stackToPrepend = (new Error()).stack.split("\n").slice(3); | ||
var mainStack = err.stack.split("\n"); | ||
var errTitle = mainStack.shift(); | ||
err.stack = [errTitle].concat(stackToPrepend, "====", mainStack).join("\n"); | ||
return err; | ||
}; |
@@ -1,18 +0,8 @@ | ||
var util = require('util'); | ||
function AlreadyInUseError(entityName, arg1, arg2, arg3, arg4) { | ||
this.entityname = entityName; | ||
var args = []; | ||
for(var i=1; i<Object.keys(arguments).length; i++) { | ||
if(arguments.hasOwnProperty(i)) args.push(arguments[i]); | ||
var generateClass = require('./helpers/class-generator'); | ||
module.exports = generateClass("AlreadyInUseError", { | ||
args: ['entity_name', 'arg1', 'arg2', 'arg3', 'arg4'], | ||
generateMessage: function(){ | ||
var args = Array.prototype.slice.call(this.args, 1); | ||
return "The specified '" + this.entity_name + "' value is already in use for: " + args.join(', '); | ||
} | ||
this.arguments = args; | ||
this.message = "The specified '" + entityName + "' value is already in use for: " + args.join(', '); | ||
this.name = "AlreadyInUseError"; | ||
Error.captureStackTrace(this, AlreadyInUseError); | ||
return this; | ||
} | ||
util.inherits(AlreadyInUseError, Error); | ||
module.exports = AlreadyInUseError; | ||
}) |
@@ -1,13 +0,7 @@ | ||
var util = require('util'); | ||
function ArgumentError(argumentName) { | ||
this.argumentName = argumentName; | ||
this.message = "Invalid or missing argument supplied: " + argumentName; | ||
this.name = "ArgumentError"; | ||
Error.captureStackTrace(this, ArgumentError); | ||
return this; | ||
} | ||
util.inherits(ArgumentError, Error); | ||
module.exports = ArgumentError; | ||
var generateClass = require('./helpers/class-generator'); | ||
module.exports = generateClass("ArgumentError", { | ||
args: ['argumentName', 'inner_error'], | ||
generateMessage: function(){ | ||
return "Invalid or missing argument supplied: " + this.argumentName; | ||
} | ||
}) |
@@ -1,13 +0,7 @@ | ||
var util = require('util'); | ||
function ArgumentNullError(argumentName) { | ||
this.argumentName = argumentName; | ||
this.message = "Missing argument: " + argumentName; | ||
this.name = "ArgumentNullError"; | ||
Error.captureStackTrace(this, ArgumentNullError); | ||
return this; | ||
} | ||
util.inherits(ArgumentNullError, Error); | ||
module.exports = ArgumentNullError; | ||
var generateClass = require('./helpers/class-generator'); | ||
module.exports = generateClass("ArgumentNullError", { | ||
args: ['argumentName', 'inner_error'], | ||
generateMessage: function(){ | ||
return "Missing argument: " + this.argumentName; | ||
} | ||
}) |
@@ -1,12 +0,7 @@ | ||
var util = require('util'); | ||
function AuthenticationRequiredError(message) { | ||
this.name = "AuthenticationRequiredError"; | ||
this.message = "An attempt was made to perform an operation without authentication: " + message; | ||
Error.captureStackTrace(this, AuthenticationRequiredError); | ||
return this; | ||
} | ||
util.inherits(AuthenticationRequiredError, Error); | ||
module.exports = AuthenticationRequiredError; | ||
var generateClass = require('./helpers/class-generator'); | ||
module.exports = generateClass("AuthenticationRequiredError", { | ||
args: ['message', 'inner_error'], | ||
generateMessage: function(){ | ||
return "An attempt was made to perform an operation without authentication: " + this.message; | ||
} | ||
}) |
@@ -10,4 +10,2 @@ var util = require('util'); | ||
} | ||
return this; | ||
} | ||
@@ -14,0 +12,0 @@ GenericError.prototype = new Error(); |
var util = require('util'); | ||
function HttpStatusError(message, statusCode) { | ||
this.message = message; | ||
var STATUS_CODE_ATTRIBUTE_NAME = module.exports.STATUS_CODE_ATTRIBUTE_NAME = 'status'; | ||
var HttpStatusError = module.exports = function HttpStatusError(status_code, message) { | ||
if(typeof message == 'number' && typeof status_code != 'number') { | ||
//old interface, so swap. | ||
var c = message; | ||
message = status_code; | ||
status_code = c; | ||
} else if(status_code instanceof Error) { | ||
var err = status_code; | ||
var req = message; | ||
status_code = err[STATUS_CODE_ATTRIBUTE_NAME]; | ||
if(typeof status_code != "number") { | ||
status_code = code_map[err.name]; | ||
if(typeof status_code == "function") { | ||
status_code(err, req); | ||
status_code = err.status_code; | ||
} | ||
status_code = status_code || 500; | ||
} | ||
message = err.message; | ||
this.stack = err.stack; | ||
} | ||
this.status_code = this[STATUS_CODE_ATTRIBUTE_NAME] = status_code || 500; | ||
this.name = "HttpStatusError"; | ||
this.statusCode = this.status = statusCode || 500; | ||
Error.captureStackTrace(this, HttpStatusError); | ||
this.stack = "(" + this.statusCode + ") " + this.stack; | ||
return this; | ||
var http_message = "(" + this.status_code + ") " + message_map[status_code] || message_map[status_code >= 500 ? 500 : 400]; | ||
this.message = message || http_message; | ||
if(!this.stack) Error.captureStackTrace(this, HttpStatusError); | ||
if(message) this.stack = http_message + "\n" + this.stack; | ||
} | ||
util.inherits(HttpStatusError, Error); | ||
module.exports = HttpStatusError; | ||
var code_map = HttpStatusError.code_map = { | ||
"ValidationError": 400, | ||
"ArgumentError": 400, | ||
"AuthenticationRequiredError": 401, | ||
"NotPermittedError": 403, | ||
"ArgumentNullError": function(err, req){ | ||
var method = req && req.method || 'GET'; | ||
var params = req && req.params || {}; | ||
if(/GET|HEAD/i.test(method) || params.hasOwnProperty(err.argumentName)) err.status_code = 404; | ||
else err.status_code = 400; | ||
err.message = err.message.replace(new RegExp("^Missing argument: (" + err.argumentName + ")$"), 'Not Found: "$1"' ); | ||
}, | ||
"NotSupportedError": 405, | ||
"AlreadyInUseError": 409, | ||
}; | ||
var message_map = HttpStatusError.message_map = { | ||
400: "Bad Request!", | ||
401: "Authentication Required!", | ||
402: "Payment Required!", | ||
403: "Forbidden!", | ||
404: "Not Found!", | ||
405: "Method not Allowed!", | ||
406: "Response Type Not Acceptable!", | ||
407: "Proxy Authentication Required!", | ||
408: "Request Timeout!", | ||
409: "Conflict!", | ||
410: "Gone!", | ||
411: "Content-Length Required!", | ||
412: "Precondition Failed!", | ||
413: "Request Entity Too Lage!", | ||
414: "Request URI Too Long!", | ||
415: "Unsupported Media Type!", | ||
416: "Requested Range Not Satisfiable!", | ||
417: "Expectation Failed!", | ||
429: "Too Many Requests!", | ||
500: "Internal Server Error!", | ||
501: "Not Implemented!", | ||
502: "Bad Gateway!", | ||
503: "Service Unavailable!", | ||
504: "Gateway Timeout!", | ||
505: "HTTP Version Not Supported!" | ||
}; | ||
@@ -0,1 +1,3 @@ | ||
var HttpStatusError = require('../http-status'); | ||
module.exports = function errorHandler(err, req, res, next){ | ||
@@ -7,40 +9,9 @@ if(!err) { | ||
var defaultMessages = { | ||
400: "Bad Request!", | ||
401: "Authorization Required!", | ||
403: "Forbidden!", | ||
405: "Method not allowed!", | ||
406: "Response Type Not Acceptable!", | ||
408: "Request Timeout!", | ||
409: "Conflict!", | ||
412: "Precondition Failed!", | ||
500: "Internal Server Error!" | ||
} | ||
var statusCode, message; | ||
if(err.name == "ArgumentNullError") { | ||
if(/GET|HEAD/i.test(req.method) || req.params.hasOwnProperty(err.argumentName)) statusCode = 404; | ||
else statusCode = 400; | ||
message = err.message.replace(new RegExp("^Missing argument: (" + err.argumentName + ")$"), 'Not Found: "$1"' ) | ||
} else if(err.name == "NotPermittedError") statusCode = 403; | ||
else if(err.name == "AlreadyInUseError") statusCode = 409; | ||
else if(err.name == "ValidationError") statusCode = 400; | ||
else if(err.name == "AuthenticationRequiredError") statusCode = 401; | ||
else if(err.name == "HttpStatusError") statusCode = err.statusCode; | ||
else statusCode = 500; | ||
if(err.status) statusCode = err.status; | ||
message = message || err.message || defaultMessages[statusCode]; | ||
if (statusCode >= 500) { | ||
message = defaultMessages[500]; | ||
err = new HttpStatusError(err, req); | ||
if(err.status_code >= 500) { | ||
console.error(err.stack); | ||
err.message = HttpStatusError.message_map[500]; //hide the real error from user agent. | ||
} | ||
if (!message) { | ||
message = defaultMessages[400]; | ||
} | ||
res.send(statusCode, message); | ||
res.send(err.status_code, err.message); | ||
} |
@@ -1,12 +0,7 @@ | ||
var util = require('util'); | ||
function NotSupportedError(message) { | ||
this.message = "Not Supported: " + message; | ||
this.name = "NotSupportedError"; | ||
Error.captureStackTrace(this, NotSupportedError); | ||
return this; | ||
} | ||
util.inherits(NotSupportedError, Error); | ||
module.exports = NotSupportedError; | ||
var generateClass = require('./helpers/class-generator'); | ||
module.exports = generateClass("NotSupportedError", { | ||
args: ['message', 'inner_error'], | ||
generateMessage: function(){ | ||
return "Not Supported: " + this.message; | ||
} | ||
}) |
@@ -1,11 +0,7 @@ | ||
var util = require('util'); | ||
function NotPermittedError(message) { | ||
this.name = "NotPermittedError"; | ||
this.message = "An attempt was made to perform an operation that is invalid: " + message; | ||
Error.captureStackTrace(this, NotPermittedError); | ||
return this; | ||
} | ||
util.inherits(NotPermittedError, Error); | ||
module.exports = NotPermittedError; | ||
var generateClass = require('./helpers/class-generator'); | ||
module.exports = generateClass("NotPermittedError", { | ||
args: ['message', 'inner_error'], | ||
generateMessage: function(){ | ||
return "An attempt was made to perform an operation that is invalid: " + this.message; | ||
} | ||
}) |
@@ -5,3 +5,3 @@ { | ||
"description": "Common error classes and utility functions", | ||
"version": "0.1.8", | ||
"version": "0.3.1", | ||
"repository": { | ||
@@ -20,3 +20,5 @@ "type": "git", | ||
"devDependencies": { | ||
"nodeunit": "= 0.7.4" | ||
"mocha": "*", | ||
"sinon": "*", | ||
"lodash": "= 2.4.1" | ||
}, | ||
@@ -38,3 +40,3 @@ "keywords": [ | ||
"scripts": { | ||
"test": "nodeunit tests" | ||
"test": "mocha --recursive tests" | ||
}, | ||
@@ -41,0 +43,0 @@ "main": "index.js", |
177
README.md
@@ -11,9 +11,9 @@ node-errors | ||
* [AlreadyInUseError](#alreadyinuse) | ||
* [NotSupportedError](#notsupported) | ||
* [ArgumentError](#argument) | ||
* [ArgumentNullError](#argumentnull) | ||
* [AuthenticationRequiredError](#authrequired) | ||
* [GenericError](#generic) | ||
* [HttpStatusError](#httpstatus) | ||
* [NotPermittedError](#notpermitted) | ||
* [AuthenticationRequiredError](#authrequired) | ||
* [NotSupportedError](#notsupported) | ||
* [ValidationError](#validation) | ||
@@ -24,2 +24,3 @@ | ||
* [log](#log) | ||
* [generateClass](#generateClass) | ||
@@ -38,10 +39,11 @@ ### Express Middleware Functions | ||
new ArgumentNullError(entityName, arg1, [arg2, arg3, arg4, ...]) | ||
__Arguments__ | ||
new ArgumentNullError(entityName, arg1, [arg2, arg3, arg4, ...]) | ||
* `entityName` - the entity that owns the protected resource | ||
* `args` - the fields or attributes that are already in use | ||
* entityName - the entity that owns the protected resource | ||
* args - the fields or attributes that are already in use | ||
```js | ||
// Example | ||
throw new errors.ArgumentNull('user', 'username'); | ||
@@ -52,15 +54,16 @@ ``` | ||
<a name="notsupported" /> | ||
### NotSupportedError | ||
<a name="argument" /> | ||
### ArgumentError | ||
Applicable when a certain condition is not supported by your application. | ||
Applicable when there's a generic problem with an argument received by a function call. | ||
new ArgumentError(argumentName) | ||
__Arguments__ | ||
new NotSupportedError(message) | ||
* `argumentName` - the name of the argument that has a problem | ||
* message - a message | ||
```js | ||
throw new errors.NotSupported('Zero values'); | ||
// Example | ||
throw new errors.Argument('username'); | ||
``` | ||
@@ -70,15 +73,16 @@ | ||
<a name="argument" /> | ||
### ArgumentError | ||
<a name="argumentnull" /> | ||
### ArgumentNullError | ||
Applicable when there's a generic problem with an argument received by a function call. | ||
Applicable when an argument received by a function call is null/undefined or empty. | ||
new ArgumentNullError(argumentName) | ||
__Arguments__ | ||
new ArgumentError(argumentName) | ||
* `argumentName` - the name of the argument that is null | ||
* argumentName - the name of the argument that has a problem | ||
```js | ||
throw new errors.Argument('username'); | ||
// Example | ||
throw new errors.ArgumentNull('username'); | ||
``` | ||
@@ -88,15 +92,16 @@ | ||
<a name="argumentnull" /> | ||
### ArgumentNullError | ||
<a name="authrequired" /> | ||
### AuthenticationRequiredError | ||
Applicable when an argument received by a function call is null/undefined or empty. | ||
Applicable when an operation requires authentication | ||
new AuthenticationRequiredError(message) | ||
__Arguments__ | ||
new ArgumentNullError(argumentName) | ||
* `message` - any message | ||
* argumentName - the name of the argument that is null | ||
```js | ||
throw new errors.ArgumentNull('username'); | ||
// Example | ||
throw new errors.AuthenticationRequiredError("Please provide authentication.") | ||
``` | ||
@@ -113,14 +118,15 @@ | ||
show the the stack where it was consumed. | ||
For example, if you perform a SQL query that returns an error with the callback, you don't know where in *your* code the offending | ||
For example, if you perform a SQL query that returns an error with the callback, you don't know where in *your* `code` the offending | ||
query was generated. Wrapping the returned error in your own GenericError will solve this problem. | ||
new GenericError(message[, innerError]) | ||
__Arguments__ | ||
new GenericError(message[, innerError]) | ||
* `message` - any message you want | ||
* `innerError` - any error that you want to preserve with the new error | ||
* message - any message you want | ||
* innerError - any error that you want to preserve with the new error | ||
```js | ||
mysql.query('SELECT * FROM users', function(err, results){ | ||
// Example | ||
mysql.query('SELECT * `FROM` users', function(err, results){ | ||
if(err) return new errors.Generic("Had trouble retrieving users.", err); | ||
@@ -138,28 +144,29 @@ console.log(results); | ||
new HttpStatusError(status_code[, message]) | ||
__Arguments__ | ||
new HttpStatusError(message, statusCode) | ||
* `status_code` - any HTTP status code integer | ||
* `message` - any message | ||
* message - any message | ||
* statusCode - any HTTP status code integer | ||
```js | ||
// Example | ||
throw new errors.HttpStatus("Not Found", 404); | ||
``` | ||
--------------------------------------- | ||
new HttpStatusError(err[, req]) | ||
<a name="authrequired" /> | ||
### AuthenticationRequiredError | ||
Figure out a proper status code and message from a given error. | ||
To change the mappings, modify `HttpStatusError.message_map` and `HttpStatusError.code_map` | ||
Applicable when an operation requires authentication | ||
__Arguments__ | ||
new AuthenticationRequiredError(message) | ||
* `err` - any Error subclass | ||
* `req` - the request object | ||
* message - any message | ||
```js | ||
throw new errors.AuthenticationRequiredError("Please provide authentication.") | ||
// Example | ||
throw new errors.HttpStatus("Not Found", 404); | ||
``` | ||
@@ -174,9 +181,10 @@ | ||
new NotPermittedError(message) | ||
__Arguments__ | ||
new NotPermittedError(message) | ||
* `message` - any message | ||
* message - any message | ||
```js | ||
// Example | ||
throw new errors.NotPermitted("username cannot be changed once set.") | ||
@@ -187,2 +195,20 @@ ``` | ||
<a name="notsupported" /> | ||
### NotSupportedError | ||
Applicable when a certain condition is not supported by your application. | ||
new NotSupportedError(message) | ||
__Arguments__ | ||
* `message` - a message | ||
```js | ||
// Example | ||
throw new errors.NotSupported('Zero values'); | ||
``` | ||
--------------------------------------- | ||
<a name="validation" /> | ||
@@ -193,10 +219,11 @@ ### ValidationError | ||
new ValidationError(message[, code]) | ||
__Arguments__ | ||
new ValidationError(message[, code]) | ||
* `message` - any message | ||
* `code` - an optional error code | ||
* message - any message | ||
* code - an optional error code | ||
```js | ||
// Example | ||
function validateUsername(username){ | ||
@@ -215,13 +242,14 @@ var errors = []; | ||
Wraps a given error in a GenericError and logs it to *stderr*. Useful for logging errors received by a callback. | ||
Modifies an error's stack to include the current stack and logs it to *stderr*. Useful for logging errors received by a callback. | ||
log(err[, message]) | ||
__Arguments__ | ||
log(err[, message]) | ||
* `err` - any error or error message received from a callback | ||
* `message` - any message you'd like to prepend | ||
* err - any error or error message received from a callback | ||
* message - any message you'd like to prepend | ||
```js | ||
mysql.query('SELECT * FROM users', function(err, results){ | ||
// Example | ||
mysql.query('SELECT * `FROM` users', function(err, results){ | ||
if(err) return errors.log(err, "Had trouble retrieving users."); | ||
@@ -232,2 +260,31 @@ console.log(results); | ||
<a name="generateClass" /> | ||
### generateClass | ||
Simple interface for generating a new Error class type. | ||
helpers.generateClass(name[, options]) | ||
__Arguments__ | ||
* `name` - The full name of the new Error class | ||
* `options` | ||
* `subclass` - The base class for the new Error class. Default is `Error`. | ||
* `args` - Array of names of values to accept and store from the class constructor. Default is `['message']`. | ||
* `generateMessage` - A function for defining a custom error message. | ||
```js | ||
// Example | ||
var ArgumentNullError = helpers.generateClass("ArgumentNullError", { | ||
subclass: ArgumentError, | ||
args: ['argumentName'], | ||
generateMessage: function(){ | ||
return "Missing argument: " + this.argumentName; | ||
} | ||
}); | ||
throw new ArgumentNullError("username"); | ||
``` | ||
## Express Middleware Functions | ||
@@ -242,2 +299,3 @@ | ||
```js | ||
// Example | ||
var app = express(); | ||
@@ -265,2 +323,3 @@ | ||
```js | ||
// Example | ||
var app = express(); | ||
@@ -292,3 +351,3 @@ | ||
Copyright (C) 2013 by Shutterstock Images, LLC | ||
Copyright (C) 2013-2014 by Shutterstock Images, LLC | ||
@@ -295,0 +354,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
@@ -0,8 +1,10 @@ | ||
var assert = require('assert'); | ||
var AuthenticationRequired = require('..').AuthenticationRequired; | ||
exports["AuthenticationRequired"] = function (test) { | ||
var error = new AuthenticationRequired("Test Message"); | ||
test.equals(error.name, "AuthenticationRequiredError"), 'Did we get the correct error name?'; | ||
test.equals(error.message, "An attempt was made to perform an operation without authentication: Test Message"); | ||
test.done(); | ||
}; | ||
describe("AuthenticatedRequiredError", function(){ | ||
it("should accept a message", function(){ | ||
var error = new AuthenticationRequired("Test Message"); | ||
assert.equal(error.name, "AuthenticationRequiredError"), 'Did we get the correct error name?'; | ||
assert.equal(error.message, "An attempt was made to perform an operation without authentication: Test Message"); | ||
}); | ||
}); |
141
tests/log.js
var errors = require('../'); | ||
var _ = require('lodash'); | ||
var assert = require('assert'); | ||
var consoleFunctions = {}; | ||
Object.keys(console).forEach(function(key){ | ||
consoleFunctions[key] = console[key]; | ||
}); | ||
describe("errors.log", function(){ | ||
var errorLog; | ||
module.exports.setUp = function(cb){ | ||
errorLog = []; | ||
var consoleFunctions = {}; | ||
Object.keys(console).forEach(function(key){ | ||
consoleFunctions[key] = console[key]; | ||
}); | ||
console.error = function(message){ | ||
if(message && message.message) errorLog.push(message.message); | ||
else errorLog.push(message); | ||
}; | ||
var errorLog; | ||
cb(); | ||
} | ||
beforeEach(function(cb){ | ||
errorLog = []; | ||
module.exports.tearDown = function(cb){ | ||
Object.keys(consoleFunctions).forEach(function(key){ | ||
console[key] = consoleFunctions[key]; | ||
console.error = function(message){ | ||
if(message && message.message) errorLog.push(message.message); | ||
else errorLog.push(message); | ||
}; | ||
cb(); | ||
}); | ||
cb(); | ||
} | ||
module.exports["log message"] = function(test){ | ||
var err = new Error("This is a test."); | ||
var err2 = errors.log(err, "Panic!"); | ||
test.equals(errorLog.length, 1); | ||
test.ok(/GenericError: Panic!/.test(errorLog[0]), 'message matches'); | ||
test.equals(err, err2.innerError); | ||
test.ok(err2.isLogged); | ||
test.done(); | ||
} | ||
afterEach(function(cb){ | ||
Object.keys(consoleFunctions).forEach(function(key){ | ||
console[key] = consoleFunctions[key]; | ||
}); | ||
cb(); | ||
}) | ||
module.exports["log string error"] = function(test){ | ||
var err2 = errors.log("Panic!"); | ||
test.equals(errorLog.length, 1); | ||
test.ok(/GenericError: Panic!/.test(errorLog[0]), 'message matches'); | ||
test.ok(!err2.innerError, 'no inner error'); | ||
test.ok(err2.isLogged); | ||
test.done(); | ||
} | ||
var logAnError = function (err, message) { | ||
return errors.log(err, message) | ||
} | ||
module.exports["log error, no message"] = function(test){ | ||
var err = new Error("This is a test."); | ||
var err2 = errors.log(err); | ||
test.equals(errorLog.length, 1); | ||
test.ok(/GenericError: A generic error has occurred./.test(errorLog[0]), "message matches"); | ||
test.equals(err, err2.innerError) | ||
test.ok(err2.isLogged); | ||
test.done(); | ||
} | ||
it("should log a message", function(){ | ||
var err = new Error("This is a assert."); | ||
var err2 = logAnError(err, "Panic!"); | ||
assert.equal(errorLog.length, 1); | ||
assert.ok(/Error: Panic!/.test(errorLog[0]), 'message matches'); | ||
assert.ok(err2.isLogged); | ||
assert.ok(err2 instanceof Error, 'we have a javascript error object'); | ||
module.exports["log generic error"] = function(test){ | ||
var err = new errors.Generic("This is a test."); | ||
var err2 = errors.log(err); | ||
test.equals(errorLog.length, 1); | ||
test.ok(/GenericError: This is a test./.test(errorLog[0]), "message matches"); | ||
test.ok(!err2.innerError); | ||
test.ok(err2.isLogged); | ||
test.done(); | ||
} | ||
var stack = err2.stack.split("\n"); | ||
assert.ok(/logAnError/.test(stack[1]), 'we prepend the current stack trace'); | ||
var splitterIndex = _(stack).findIndex(function(item){return item == '===='}); | ||
assert.ok(splitterIndex, 'we spit the stacks with "===="'); | ||
assert.ok(/Context\.<anonymous>/.test(stack.slice(splitterIndex)[1]), 'we keep the old stack trace'); | ||
}); | ||
module.exports["log generic error again"] = function(test){ | ||
var err = new errors.Generic("This is a test."); | ||
err.isLogged = true; | ||
var err2 = errors.log(err); | ||
test.equals(errorLog.length, 1); | ||
test.ok(/GenericError: A generic error has occurred./.test(errorLog[0]), "message matches"); | ||
test.equals(err, err2.innerError) | ||
test.ok(err2.isLogged); | ||
test.done(); | ||
} | ||
it("log string error", function(){ | ||
var err2 = logAnError("Panic!"); | ||
assert.equal(errorLog.length, 1); | ||
assert.ok(/GenericError: Panic!/.test(errorLog[0]), 'message matches'); | ||
assert.ok(err2.isLogged); | ||
assert.ok(err2 instanceof errors.Generic, 'we have a generic error'); | ||
assert.ok(!/====[ ]/.test(errorLog[0]), "we don't prepend any stack traces"); | ||
}) | ||
it("log error, no message", function(){ | ||
var err = new Error("This is a assert."); | ||
var err2 = logAnError(err); | ||
assert.equal(errorLog.length, 1); | ||
assert.ok(/Error: This is a assert./.test(errorLog[0]), "message matches"); | ||
var stack = err2.stack.split("\n"); | ||
assert.ok(/logAnError/.test(stack[1]), 'we prepend the current stack trace'); | ||
var splitterIndex = _(stack).findIndex(function(item){return item == '===='}); | ||
assert.ok(splitterIndex, 'we spit the stacks with "===="'); | ||
assert.ok(/Context\.<anonymous>/.test(stack.slice(splitterIndex)[1]), 'we keep the old stack trace'); | ||
assert.ok(err2 instanceof Error, 'we have a javascript error object'); | ||
assert.ok(err2.isLogged); | ||
}) | ||
it("log generic error", function(){ | ||
var err = new errors.Generic("This is a assert."); | ||
var err2 = logAnError(err); | ||
assert.equal(errorLog.length, 1); | ||
assert.ok(/GenericError: This is a assert./.test(errorLog[0]), "message matches"); | ||
assert.ok(err2 instanceof errors.Generic, 'we have a generic error'); | ||
assert.ok(err2.isLogged); | ||
var stack = err2.stack.split("\n"); | ||
assert.ok(/logAnError/.test(stack[1]), 'we prepend the current stack trace'); | ||
var splitterIndex = _(stack).findIndex(function(item){return item == '===='}); | ||
assert.ok(splitterIndex, 'we spit the stacks with "===="'); | ||
assert.ok(/Context\.<anonymous>/.test(stack.slice(splitterIndex)[1]), 'we keep the old stack trace'); | ||
}); | ||
}) |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
29949
65.48%23
35.29%508
84.73%347
20.49%3
200%2
Infinity%