diff --git a/Makefile b/Makefile index 0f9ef70..ec05e6d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ # # Directories # -NODE_MODULES := './node_modules' +ROOT := $(shell pwd) +NODE_MODULES := $(ROOT)/node_modules NODE_BIN := $(NODE_MODULES)/.bin @@ -22,11 +23,12 @@ NPM := npm # GIT_HOOK_SRC = '../../tools/githooks/pre-push' GIT_HOOK_DEST = '.git/hooks/pre-push' -LIB_FILES = './lib' -TEST_FILES = './test' -COVERAGE_FILES = './coverage' -LCOV = './coverage/lcov.info' - +LIB_FILES := $(ROOT)/lib +TEST_FILES := $(ROOT)/test +COVERAGE_FILES := $(ROOT)/coverage +LCOV := $(ROOT)/coverage/lcov.info +SRCS := $(shell find $(LIB_FILES) $(TEST_FILES) -name '*.js' -type f \ + -not \( -path './node_modules/*' -prune \)) # # Targets @@ -48,18 +50,18 @@ githooks: .PHONY: lint -lint: node_modules - $(ESLINT) $(LIB_FILES) $(TEST_FILES) +lint: node_modules $(ESLINT) $(SRCS) + $(ESLINT) $(SRCS) .PHONY: codestyle -codestyle: node_modules - $(JSCS) $(LIB_FILES) $(TEST_FILES) +codestyle: node_modules $(JSCS) $(SRCS) + $(JSCS) $(SRCS) .PHONY: codestyle-fix -codestyle-fix: node_modules - $(JSCS) $(LIB_FILES) $(TEST_FILES) --fix +codestyle-fix: node_modules $(JSCS) $(SRCS) + $(JSCS) $(SRCS) --fix .PHONY: prepush @@ -77,7 +79,7 @@ coverage: node_modules clean-coverage .PHONY: report-coverage -report: coverage +report-coverage: coverage @cat $(LCOV) | $(COVERALLS) @@ -94,4 +96,4 @@ clean: clean-coverage # ## Debug -- print out a a variable via `make print-FOO` # -#print-% : ; @echo $* = $($*) +print-% : ; @echo $* = $($*) diff --git a/README.md b/README.md index eccf462..919e7dd 100644 --- a/README.md +++ b/README.md @@ -222,14 +222,15 @@ For more information about building rich errors, check out ### Subclassing Errors You can also create your own Error subclasses by using the provided -`makeConstructor()` method: +`makeConstructor()` method. Making a new subclass will add the constructor to +the existing exports object: ```js -var ExecutionError = errors.makeConstructor('ExecutionError', { +errors.makeConstructor('ExecutionError', { statusCode: 406, failureType: 'motion' }); -var myErr = new ExecutionError('bad joystick input!'); +var myErr = new errors.ExecutionError('bad joystick input!'); console.log(myErr instanceof ExecutionError); // => true @@ -300,13 +301,13 @@ prefer that over `options.message`. ### makeConstructor(name [, defaults]) -Creates a custom Error constructor. +Creates a custom Error constructor, adds it to the existing exports object. * `name` {String} - the name of your Error * `defaults` {Object} - an object of default values that will added to the prototype. -**Returns:** {Function} an Error constructor, inherits from RestError +**Returns:** {void} ### makeErrFromCode(name [, args...]) diff --git a/lib/index.js b/lib/index.js index 839b9d7..15c6610 100644 --- a/lib/index.js +++ b/lib/index.js @@ -54,6 +54,10 @@ function makeConstructor(name, defaults) { assert.string(name, 'name'); assert.optionalObject(defaults, 'defaults'); + // assert that this constructor doesn't already exist. + assert.equal(typeof module.exports[name], 'undefined', + 'Constructor already exists!'); + // dynamically create a constructor. // must be anonymous fn. var ErrCtor = function() { @@ -67,8 +71,8 @@ function makeConstructor(name, defaults) { // copy over defaults _.assign(ErrCtor.prototype, defaults); - // return the ctor - return ErrCtor; + // store constructor on main exports + module.exports[name] = ErrCtor; } diff --git a/package.json b/package.json index f47fe4c..d4975a0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "main": "lib/index.js", "description": "Collection of Error objects shared across restify components.", - "homepage": "", + "homepage": "http://www.restify.com", "author": { "name": "Alex Liu", "email": "donutespresso@gmail.com" @@ -15,7 +15,7 @@ ], "repository": { "type": "git", - "url": "" + "url": "https://github.com/restify/errors.git" }, "license": "MIT", "files": [ @@ -25,15 +25,19 @@ "restify-errors", "restify", "errors", - "restify-clients" + "custom errors", + "inherit errors", + "http errors", + "http status code", + "rest errors" ], "scripts": { - "test": "make test" + "test": "make test" }, "devDependencies": { "chai": "^3.0.0", "coveralls": "^2.11.2", - "eslint": "^0.23.0", + "eslint": "^0.24.0", "istanbul": "^0.3.15", "jscs": "^1.13.1", "mkdirp": "^0.5.1", diff --git a/test/index.js b/test/index.js index 95e8ddc..13f8d60 100644 --- a/test/index.js +++ b/test/index.js @@ -382,11 +382,11 @@ describe('restify-errors node module.', function() { }); it('should have test file as first line of subclass error stack trace', function testStack5() { - var ExecutionError = restifyErrors.makeConstructor('ExecutionError'); - var err = new ExecutionError('did not charge long enough'); + restifyErrors.makeConstructor('ChargeError'); + var err = new restifyErrors.ChargeError('did not charge long enough'); var stack = err.stack.split('\n'); - assert.equal(_.includes(stack[0], 'ExecutionError: did not charge long enough'), true); + assert.equal(_.includes(stack[0], 'ChargeError: did not charge long enough'), true); assert.equal(_.includes(stack[1], 'Context.testStack5'), true); assert.equal(_.includes(stack[1], 'test/index.js'), true); }); @@ -460,15 +460,15 @@ describe('restify-errors node module.', function() { }); }); - it('should create custom error using "make"', function() { + it('should create custom error using makeConstructor', function() { var underlyingErr = new Error('underlying error!'); - var ExecutionError = restifyErrors.makeConstructor('ExecutionError', { + restifyErrors.makeConstructor('ExecutionError', { statusCode: 406, failureType: 'motion' }); - var err = new ExecutionError(underlyingErr, 'bad joystick input'); + var err = new restifyErrors.ExecutionError(underlyingErr, 'bad joystick input'); - assert.equal(err instanceof ExecutionError, true); + assert.equal(err instanceof restifyErrors.ExecutionError, true); assert.equal(err instanceof RestError, true); assert.equal(err instanceof HttpError, true); assert.equal(err instanceof WError, true); @@ -482,6 +482,16 @@ describe('restify-errors node module.', function() { assert.equal(err.we_cause, underlyingErr); }); + it('should throw when creating a constructor that already exists', function() { + assert.throws(function() { + restifyErrors.makeConstructor('ExecutionError'); + }, 'Constructor already exists!'); + + assert.throws(function() { + restifyErrors.makeConstructor('InternalServerError'); + }, 'Constructor already exists!'); + }); + it('should create an error from an http status code', function() { var err = restifyErrors.makeErrFromCode(406, 'the horror');