Permalink
Browse files

Refactor internals

  • Loading branch information...
1 parent 7235290 commit a2725fbe44bfd0426045950bffe9c683148afd1f @dougwilson dougwilson committed Apr 3, 2016
Showing with 146 additions and 56 deletions.
  1. +1 −0 LICENSE
  2. +145 −56 index.js
View
@@ -2,6 +2,7 @@
The MIT License (MIT)
Copyright (c) 2014 Jonathan Ong me@jongleberry.com
+Copyright (c) 2016 Douglas Christopher Wilson doug@somethingdoug.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
View
@@ -1,19 +1,37 @@
/*!
* http-errors
* Copyright(c) 2014 Jonathan Ong
+ * Copyright(c) 2016 Douglas Christopher Wilson
* MIT Licensed
*/
+/**
+ * Module dependencies.
+ * @private
+ */
+
var statuses = require('statuses');
var inherits = require('inherits');
-function toIdentifier(str) {
- return str.split(' ').map(function (token) {
- return token.slice(0, 1).toUpperCase() + token.slice(1)
- }).join('').replace(/[^ _0-9a-z]/gi, '')
-}
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = createError
+module.exports.HttpError = createHttpErrorConstructor()
-exports = module.exports = function httpError() {
+// Populate exports for all constructors
+populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError)
+
+/**
+ * Create a new HTTP Error.
+ *
+ * @returns {Error}
+ * @public
+ */
+
+function createError () {
// so much arity going on ~_~
var err;
var msg;
@@ -44,14 +62,14 @@ exports = module.exports = function httpError() {
}
// constructor
- var HttpError = exports[status]
+ var HttpError = createError[status]
if (!err) {
// create error
err = HttpError
? new HttpError(msg)
: new Error(msg || statuses[status])
- Error.captureStackTrace(err, httpError)
+ Error.captureStackTrace(err, createError)
}
if (!HttpError || !(err instanceof HttpError)) {
@@ -67,65 +85,136 @@ exports = module.exports = function httpError() {
}
return err;
-};
+}
+
+/**
+ * Create HTTP error abstract base class.
+ * @private
+ */
+
+function createHttpErrorConstructor () {
+ function HttpError () {
+ throw new TypeError('cannot construct abstract class')
+ }
-var HttpError = exports.HttpError = function HttpError() {
- throw new TypeError('cannot construct abstract class');
-};
+ inherits(HttpError, Error)
-inherits(HttpError, Error);
+ return HttpError
+}
-// create generic error objects
-var codes = statuses.codes.filter(function (num) {
- return num >= 400;
-});
+/**
+ * Create a constructor for a client error.
+ * @private
+ */
-codes.forEach(function (code) {
- var name = toIdentifier(statuses[code])
+function createClientErrorConstructor (HttpError, name, code) {
var className = name.match(/Error$/) ? name : name + 'Error'
- if (code >= 500) {
- var ServerError = function ServerError(msg) {
- var self = new Error(msg != null ? msg : statuses[code])
- Error.captureStackTrace(self, ServerError)
- self.__proto__ = ServerError.prototype
- Object.defineProperty(self, 'name', {
- enumerable: false,
- configurable: true,
- value: className,
- writable: true
- })
- return self
- }
- inherits(ServerError, HttpError);
- ServerError.prototype.status =
- ServerError.prototype.statusCode = code;
- ServerError.prototype.expose = false;
- exports[code] =
- exports[name] = ServerError
- return;
+ function ClientError (message) {
+ // create the error object
+ var err = new Error(message != null ? message : statuses[code])
+
+ // capture a stack trace to the construction point
+ Error.captureStackTrace(err, ClientError)
+
+ // adjust the [[Prototype]]
+ err.__proto__ = ClientError.prototype
+
+ // redefine the error name
+ Object.defineProperty(err, 'name', {
+ enumerable: false,
+ configurable: true,
+ value: className,
+ writable: true
+ })
+
+ return err
}
- var ClientError = function ClientError(msg) {
- var self = new Error(msg != null ? msg : statuses[code])
- Error.captureStackTrace(self, ClientError)
- self.__proto__ = ClientError.prototype
- Object.defineProperty(self, 'name', {
+ inherits(ClientError, HttpError)
+
+ ClientError.prototype.status = code
+ ClientError.prototype.statusCode = code
+ ClientError.prototype.expose = true
+
+ return ClientError
+}
+
+/**
+ * Create a constructor for a server error.
+ * @private
+ */
+
+function createServerErrorConstructor (HttpError, name, code) {
+ var className = name.match(/Error$/) ? name : name + 'Error'
+
+ function ServerError (message) {
+ // create the error object
+ var err = new Error(message != null ? message : statuses[code])
+
+ // capture a stack trace to the construction point
+ Error.captureStackTrace(err, ServerError)
+
+ // adjust the [[Prototype]]
+ err.__proto__ = ServerError.prototype
+
+ // redefine the error name
+ Object.defineProperty(err, 'name', {
enumerable: false,
configurable: true,
value: className,
writable: true
})
- return self
+
+ return err
}
- inherits(ClientError, HttpError);
- ClientError.prototype.status =
- ClientError.prototype.statusCode = code;
- ClientError.prototype.expose = true;
- exports[code] =
- exports[name] = ClientError
- return;
-});
-
-// backwards-compatibility
-exports["I'mateapot"] = exports.ImATeapot
+
+ inherits(ServerError, HttpError)
+
+ ServerError.prototype.status = code
+ ServerError.prototype.statusCode = code
+ ServerError.prototype.expose = false
+
+ return ServerError
+}
+
+/**
+ * Populate the exports object with constructors for every error class.
+ * @private
+ */
+
+function populateConstructorExports (exports, codes, HttpError) {
+ codes.forEach(function forEachCode (code) {
+ var CodeError
+ var name = toIdentifier(statuses[code])
+
+ switch (String(code).charAt(0)) {
+ case '4':
+ CodeError = createClientErrorConstructor(HttpError, name, code)
+ break
+ case '5':
+ CodeError = createServerErrorConstructor(HttpError, name, code)
+ break
+ }
+
+ if (CodeError) {
+ // export the constructor
+ exports[code] = CodeError
+ exports[name] = CodeError
+ }
+ })
+
+ // backwards-compatibility
+ exports["I'mateapot"] = exports.ImATeapot
+}
+
+/**
+ * Convert a string of words to a JavaScript identifier.
+ * @private
+ */
+
+function toIdentifier (str) {
+ return str.split(' ').map(function (token) {
+ return token.slice(0, 1).toUpperCase() + token.slice(1)
+ }).join('').replace(/[^ _0-9a-z]/gi, '')
+}

0 comments on commit a2725fb

Please sign in to comment.