From 4d3801061b9166ae0902c8126c55b94f592ed8ca Mon Sep 17 00:00:00 2001 From: meaku Date: Mon, 26 May 2014 14:21:51 +0200 Subject: [PATCH] - initial commit --- .jshintrc | 48 ++++++++++++++++++++++++++++++++++++++++ README.md | 52 +++++++++++++++++++++++++++++++++++++++++--- errors/duplicate.js | 8 +++++++ errors/index.js | 4 ++++ errors/notFound.js | 8 +++++++ example/example.js | 40 ++++++++++++++++++++++++++++++++++ lib/AbstractError.js | 21 ++++++++++++++++++ lib/index.js | 38 ++++++++++++++++++++++++++++++++ 8 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 .jshintrc create mode 100644 errors/duplicate.js create mode 100644 errors/index.js create mode 100644 errors/notFound.js create mode 100644 example/example.js create mode 100644 lib/AbstractError.js create mode 100644 lib/index.js diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..da2bb6f --- /dev/null +++ b/.jshintrc @@ -0,0 +1,48 @@ +{ + "browser": true, + "node": true, + "expr": true, + "predef": [ // Extra globals. + "describe", + "it", + "before", + "after", + "beforeEach", + "afterEach" + ], + + "curly": true, // Require {} for every new block or scope. + "eqeqeq": true, // Require triple equals i.e. `===`. + "forin": true, // Tolerate `for in` loops without `hasOwnPrototype`. + "immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` + "latedef": true, // Prohibit variable use before definition. + "newcap": false, // Require capitalization of all constructor functions e.g. `new F()`. + "noempty": true, // Prohibit use of empty blocks. + "nonew": false, // Prohibit use of constructors for side-effects. + "plusplus": false, // Prohibit use of `++` & `--`. + "undef": false, // Require all non-global variables be declared before they are used. + "strict": true, // Require `use strict` pragma in every file. + "trailing": true, // Prohibit trailing whitespaces. + + "asi": false, // Tolerate Automatic Semicolon Insertion (no semicolons). + "boss": false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. + "debug": false, // Allow debugger statements e.g. browser breakpoints. + "eqnull": false, // Tolerate use of `== null`. + "esnext": false, // Allow ES.next specific features such as `const` and `let`. + "evil": false, // Tolerate use of `eval`. + "funcscope": false, // Tolerate declarations of variables inside of control structures while accessing them later from the outside. + "globalstrict": false, // Allow global "use strict" (also enables 'strict'). + "iterator": false, // Allow usage of __iterator__ property. + "lastsemic": false, // Tolerat missing semicolons when the it is omitted for the last statement in a one-line block. + "laxbreak": false, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons. + "laxcomma": false, // Suppress warnings about comma-first coding style. + "loopfunc": false, // Allow functions to be defined within loops. + "multistr": false, // Tolerate multi-line strings. + "proto": false, // Tolerate __proto__ property. This property is deprecated. + "scripturl": false, // Tolerate script-targeted URLs. + "smarttabs": false, // Tolerate mixed tabs and spaces when the latter are used for alignmnent only. + "shadow": false, // Allows re-define variables later in code e.g. `var x=1; x=2;`. + "sub": true, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`. + "supernew": false, // Tolerate `new function () { ... };` and `new Object;`. + "validthis": false // Tolerate strict violations when the code is running in strict mode and you use this in a non-constructor function +} \ No newline at end of file diff --git a/README.md b/README.md index c72d02a..ea6aec0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,50 @@ -erroz -===== +## erroz -Erroz ramazotti +Erroz ramazotti the way you like it. + +Create abstract errors which render speaking error-messages and contain useful meta-data like http-status-codes to be used for your api-happiness. + +### Usage + +```javascript + +var erroz = require("erroz"); + +var DuplicateError = erroz({ + name: "Duplicate", + statusCode: 409, + code: "duplicate", + message: "'%s' with id '%s' already exists." +}); + +throw new DuplicateError("User", 1); +``` + +>/example/example.js:33 + throw new DuplicateError("User", 1); + ^ + Duplicate: 'User' with id '1' already exists. + at Object. (example/example.js:39:7) + at Module._compile (module.js:456:26) + at Object.Module._extensions..js (module.js:474:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Function.Module.runMain (module.js:497:10) + at startup (node.js:119:16) + at node.js:902:3 + +### Predefined Errors + +Erroz ships with predefined errors. You can include them all at once, or individually. + +```javascript +var erroz = require("erroz"); + +//all errors +var errors = require("erroz/errors"), + DuplicateError = erroz(errors.duplicate); + + //specific error +var notFound = require("errorz/errors/notFound"), + NotFoundError = erroz(notFound); +``` \ No newline at end of file diff --git a/errors/duplicate.js b/errors/duplicate.js new file mode 100644 index 0000000..b5c7823 --- /dev/null +++ b/errors/duplicate.js @@ -0,0 +1,8 @@ +"use strict"; + +module.exports = { + name: "Duplicate", + statusCode: 409, + code: "duplicate", + message: "'%s' with id '%s' already exists." +}; \ No newline at end of file diff --git a/errors/index.js b/errors/index.js new file mode 100644 index 0000000..1b7b5ef --- /dev/null +++ b/errors/index.js @@ -0,0 +1,4 @@ +"use strict"; + +exports.duplicate = require("./duplicate.js"); +exports.notFound = require("./notFound.js"); \ No newline at end of file diff --git a/errors/notFound.js b/errors/notFound.js new file mode 100644 index 0000000..0d44092 --- /dev/null +++ b/errors/notFound.js @@ -0,0 +1,8 @@ +"use strict"; + +module.exports = { + name: "NotFound", + statusCode: 404, + code: "not-found", + message: "'%s' with id '%s' does not exist." +}; \ No newline at end of file diff --git a/example/example.js b/example/example.js new file mode 100644 index 0000000..cf3b57a --- /dev/null +++ b/example/example.js @@ -0,0 +1,40 @@ +'use strict'; + +var erroz = require("../lib/index.js"); + +var errors = { + "Duplicate": { + name: "Duplicate", + statusCode: 409, + code: "duplicate", + message: "'%s' with id '%s' already exists." + }, + "NotFound": { + name: "NotFound", + statusCode: 404, + code: "not-found", + message: "'%s' with id %s does not exist." + }, + "InvalidFields": { + name: "InvalidFields", + statusCode: 400, + code: "invalid-fields", + message: "Invalid fields: %s." + } +}; + +/** + * Generate error classes based on AbstractError + */ +var DuplicateError = erroz(errors.Duplicate), + NotFoundError = erroz(errors.NotFound), + InavalidFieldsError = erroz(errors.InvalidFields); + +throw new DuplicateError("User", 1); + + + + + + + diff --git a/lib/AbstractError.js b/lib/AbstractError.js new file mode 100644 index 0000000..371db32 --- /dev/null +++ b/lib/AbstractError.js @@ -0,0 +1,21 @@ +"use strict"; + +/** + * Custom error classes. + * Each of the classes specified below will abstract from a common + * AbstractError class, as described in this article: + * http://dustinsenos.com/articles/customErrorsInNode + */ + +var util = require("util"); + +/** + * AbstractError + */ +function AbstractError(constr) { + Error.captureStackTrace(this, constr || this); +} +util.inherits(AbstractError, Error); +AbstractError.prototype.name = "AbstractError"; + +module.exports = AbstractError; \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..c643329 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,38 @@ +"use strict"; + +var util = require("util"); + +var AbstractError = require("./AbstractError.js"); + +/** + * generate Error-classes based on AbstractError + * + * @param error + * @returns {Function} + */ +function erroz(error) { + + var errorFn = function () { + //we pass the args on to util.format to render the message + var args = Array.prototype.slice.call(arguments); + + if (args.length > 0) { + args.unshift(error.message); + this.message = util.format.apply(this, args); + } + + errorFn.super_.call(this, this.constructor); + }; + + util.inherits(errorFn, AbstractError); + + //add error properties + errorFn.prototype.name = error.name; + errorFn.prototype.statusCode = error.statusCode; + errorFn.prototype.code = error.code; + errorFn.prototype.message = error.message; + + return errorFn; +} + +module.exports = erroz; \ No newline at end of file