Skip to content

Commit 836a871

Browse files
committed
Version 1.0.0 all tests pass
0 parents  commit 836a871

25 files changed

+979
-0
lines changed

.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
node_modules
2+
3+
*.seed
4+
*.log
5+
*.dat
6+
*.out
7+
*.pid
8+
*.gz
9+
*~
10+
.idea
11+
*.sublime-project
12+
*.sublime-workspace
13+
*.orig
14+
15+
pids
16+
logs
17+
results
18+
19+
npm-debug.log
20+
21+
.coverage
22+
coverageReport.html
23+
24+

.jshintignore

Whitespace-only changes.

.jshintrc

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"predef": [
3+
"sinon",
4+
"_",
5+
"requireMockFactory",
6+
"it",
7+
"describe",
8+
"expect",
9+
"beforeEach",
10+
"before",
11+
"after",
12+
"afterEach"
13+
],
14+
15+
"node" : true,
16+
"boss" : false,
17+
"curly": true,
18+
"debug": false,
19+
"devel": false,
20+
"eqeqeq": true,
21+
"evil": false,
22+
"forin": false,
23+
"immed": true,
24+
"laxbreak": false,
25+
"newcap": true,
26+
"noarg": true,
27+
"noempty": false,
28+
"nonew": true,
29+
"onevar": false,
30+
"plusplus": false,
31+
"multistr": true,
32+
"regexp": false,
33+
"undef": true,
34+
"sub": false,
35+
"strict": true,
36+
"bitwise" : true,
37+
"curly" : true,
38+
"latedef" : false,
39+
"noarg" : true,
40+
"trailing" : true,
41+
"asi" : false,
42+
"expr": true
43+
}

.npmignore

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
node_modules
2+
3+
*.seed
4+
*.log
5+
*.dat
6+
*.out
7+
*.pid
8+
*.gz
9+
*~
10+
.idea
11+
*.sublime-project
12+
*.sublime-workspace
13+
*.orig
14+
15+
pids
16+
logs
17+
results
18+
19+
npm-debug.log
20+
21+
.coverage
22+
coverageReport.html
23+
24+
test
25+
bin
26+
.gitignore
27+
.jshintignore
28+
.jshintrc
29+
.npmignore

bin/runCoverage.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"use strict";
2+
process.env.NODE_ENV = "coverage";
3+
var fs = require("fs");
4+
5+
//make writes to stdout and stderr sync, so the process does not exit before writing output.
6+
process.stdout.write = function (data){
7+
fs.writeSync(1, data);
8+
};
9+
process.stderr.write = function (data){
10+
fs.writeSync(2, data);
11+
};
12+
13+
var nodecoverage = require("nodecoverage");
14+
nodecoverage({
15+
instrument:["lib"]
16+
}, function (err) {
17+
if(err){
18+
console.error(err);
19+
}
20+
process.exit();
21+
});

bin/runTests.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"use strict";
2+
var fs = require("fs");
3+
var path = require("path");
4+
5+
//make writes to stdout and stderr sync, so the process does not exit before writing output.
6+
process.stdout.write = function (data){
7+
fs.writeSync(1, data);
8+
};
9+
process.stderr.write = function (data){
10+
fs.writeSync(2, data);
11+
};
12+
13+
runJsHint(["lib", "test", "bin"], function (err) {
14+
if (err) {
15+
console.error("Exiting because of jsHint errors");
16+
return process.exit(1);
17+
}
18+
console.log("No JSHint errors detected");
19+
return runMocha();
20+
});
21+
22+
function runMocha() {
23+
require('../node_modules/mocha/bin/_mocha');
24+
}
25+
26+
function runJsHint(pathsArray, callback) {
27+
var jsHint = require("../node_modules/jshint/lib/hint.js");
28+
var config = JSON.parse(fs.readFileSync(path.resolve(".jshintrc"), "utf-8"));
29+
var reporter = require("../node_modules/jshint/lib/reporters/default.js").reporter;
30+
var ignores = fs.readFileSync(path.resolve(".jshintignore"), "utf8").split("\n")
31+
.filter(function (line) {
32+
return !!line.trim(); //remove empty lines
33+
})
34+
.map(path.resolve);
35+
var results = jsHint.hint(pathsArray, config, reporter, ignores);
36+
if (results.length > 0) {
37+
return callback(new Error("JSHintErrors"));
38+
}
39+
return callback(null);
40+
}

lib/middleware.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"use strict";
2+
var errors = require("./nodeerrors");
3+
module.exports = function(options){
4+
5+
return errorHandler;
6+
7+
function errorHandler(req, res, next, err){
8+
var error = errors.parse(err);
9+
req.error = JSON.parse(JSON.stringify(error)); //for logging of internal messages by logger
10+
res.statusCode = error.http;
11+
delete error.http; //do not show http code to users (it's send in header)
12+
delete error.internal; //do not show internal messages to users
13+
res.json(error);
14+
}
15+
};

lib/nodeerrors.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"use strict";
2+
var _ = require("underscore");
3+
var errorCodeSpecs = require("./util/getErrorConfig");
4+
var makeErrorFunction = require("./util/makeErrorFunction");
5+
var parse = require("./util/parse");
6+
var getSerializableError = require("./util/getSerializableError");
7+
var middleware = require("./middleware");
8+
9+
var nodeError = {
10+
errorCodes:{},
11+
parse:parse,
12+
middleware:middleware
13+
};
14+
15+
var functionsToMake = _.keys(errorCodeSpecs); //get array of freindly names.
16+
for (var i = 0; i < functionsToMake.length; i++) {
17+
//get error code freindly name, for example: "internalError"
18+
var errorCodeName = functionsToMake[i];
19+
//make error function for freindly name
20+
nodeError[errorCodeName] = makeErrorFunction(errorCodeName, errorCodeSpecs[errorCodeName]);
21+
//save the error code in errorCodes
22+
nodeError.errorCodes[errorCodeName] = errorCodeSpecs[errorCodeName].code;
23+
}
24+
25+
Error.prototype.innerError = function addInnerError(err) {
26+
var error;
27+
try {
28+
error = JSON.parse(this.message);
29+
} catch (ex) {
30+
error = {
31+
message:this.message
32+
};
33+
}
34+
error.internal = error.internal || {};
35+
error.internal.innerError = getSerializableError(err);
36+
this.message = JSON.stringify(error);
37+
return this;
38+
};
39+
40+
Function.prototype.onError = function (callback) {
41+
var fn = this;
42+
return function (err) {
43+
if (err) {
44+
return callback(err);
45+
}
46+
try {
47+
fn.apply(null, arguments);
48+
} catch (ex) {
49+
return callback(ex);
50+
}
51+
};
52+
};
53+
54+
module.exports = nodeError;

lib/util/getErrorConfig.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"use strict";
2+
var _ = require("underscore");
3+
var path = require("path");
4+
var fs = require("fs");
5+
var existsSync = fs.existsSync || path.existsSync;
6+
var CONFIG_FILE_NAME = ".errors.js";
7+
8+
function requireConfig() {
9+
var dir = path.join(__dirname, "../..");
10+
var lastDir;
11+
12+
while (lastDir !== dir) {
13+
if (existsSync(path.join(dir, CONFIG_FILE_NAME))) {
14+
return require(path.join(dir, CONFIG_FILE_NAME));
15+
}
16+
if (existsSync(path.join(dir, "config", CONFIG_FILE_NAME))) {
17+
return require(path.join(dir, "config", CONFIG_FILE_NAME));
18+
}
19+
lastDir = dir;
20+
dir = path.join(dir, "..");
21+
}
22+
return {};
23+
}
24+
var config = JSON.parse(JSON.stringify(requireConfig())); //make copy so we do not alter original
25+
if (!config.system) {
26+
config.system = {
27+
code:0,
28+
message:"There was an internal server error",
29+
http:500
30+
};
31+
}
32+
33+
module.exports = config;
34+

lib/util/getSerializableError.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"use strict";
2+
module.exports = function getSerializableError(err) {
3+
//this copying of properties is needed to get Error properties serialized by JSON.stringify
4+
var output = {};
5+
Object.getOwnPropertyNames(err).forEach(function (i) {
6+
if (err[i]) {
7+
output[i] = err[i];
8+
}
9+
});
10+
return output;
11+
};

lib/util/makeErrorFunction.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"use strict";
2+
var format = require("util").format;
3+
4+
module.exports = function makeErrorFunction(errorCodeName, errorCodeSpec) {
5+
if (!errorCodeSpec.code && errorCodeSpec.code !== 0) {
6+
throw new Error(format("The error code specification for %s, has no property 'code'", errorCodeName));
7+
}
8+
9+
return function () {
10+
var error = {}, message;
11+
error.name = errorCodeName;
12+
var i = 0;
13+
if (errorCodeSpec.args) {
14+
for (i = 0; i < errorCodeSpec.args.length; i++) {
15+
var argName = errorCodeSpec.args[i];
16+
if (arguments[i]) {
17+
error[argName] = arguments[i];
18+
}
19+
}
20+
}
21+
if(arguments[i]){
22+
error.internal = arguments[i]; //always allow additional last argument to be stored as internal
23+
}
24+
//get error message
25+
if (errorCodeSpec.args) {
26+
var formatArguments = [errorCodeSpec.message];
27+
formatArguments.push.apply(formatArguments, arguments);
28+
message = format.apply(format, formatArguments);
29+
} else {
30+
message = errorCodeSpec.message;
31+
}
32+
error.message = message;
33+
//add additional error code spec properties
34+
var properties = _.keys(errorCodeSpec);
35+
for(i=0; i<properties.length; i++){
36+
var propertyName = properties[i];
37+
if(propertyName !== "args" && propertyName !== "message"){
38+
error[propertyName] = errorCodeSpec[propertyName];
39+
}
40+
}
41+
return new Error(JSON.stringify(error));
42+
};
43+
};

lib/util/parse.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"use strict";
2+
var _ = require("underscore");
3+
var getSerializableError = require("./getSerializableError");
4+
5+
module.exports = function parseError(err) {
6+
var errors = require("../nodeerrors.js");
7+
var error;
8+
try {
9+
error = JSON.parse(err.message);
10+
error.internal = error.internal || {};
11+
_(error.internal).extend(getSerializableError(err)); //add call stack from Error object
12+
delete error.internal.message; //no need to keep JSON string, it has been de-serialized in to error object.
13+
return error;
14+
} catch (ex) {
15+
//this is not one of our errors, must be from mongo or somewhere else, no recovery possible.
16+
return parseError(errors.system().innerError(err));
17+
}
18+
};
19+

package.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"author":"Allan Ebdrup",
3+
"name":"nodeerrors",
4+
"version":"1.0.0",
5+
"repository":{
6+
"type":"git",
7+
"url":"https://github.com/Muscula/nodeerrors"
8+
},
9+
"private":false,
10+
"main":"./lib/nodeerrors.js",
11+
"engines":{
12+
"node":">=0.6.20",
13+
"npm":">=1.1.9"
14+
},
15+
"dependencies":{
16+
"underscore":"~1.3.1"
17+
},
18+
"scripts":{
19+
"test":"node ./bin/runTests.js",
20+
"cov":"node ./bin/runCoverage.js"
21+
},
22+
"devDependencies":{
23+
"mocha":"",
24+
"chai":"",
25+
"sinon":"",
26+
"sinon-chai":"",
27+
"jshint":"",
28+
"nodecoverage":">=0.6.5",
29+
"requiremock": ">=1.3.3"
30+
}
31+
}

0 commit comments

Comments
 (0)