diff --git a/README.md b/README.md index cec8ea7..3a47697 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ app.listen(3000); ```javascript const Error = require("throw.js/CustomError"); -Error(message, statusCode, errorCode); +throw new Error(message, statusCode?, errorCode?, originalError?); ``` Parameters: @@ -53,6 +53,19 @@ Parameters: - **statusCode**[optional]: The HTTP Status number to return - **errorCode**[optional]: An internal unique code identifier of this error +## Stacking Errors + +```javascript +const Error = require("throw.js/CustomError"); + +try { + // throws an error +} catch (e) { + // Pass the error as a parameter to keep its original stack trace + throw new Error(message, statusCode, errorCode, e); +} +``` + ## Errors All of the classes below have all parameters set up by default, based on [RFC7231](http://tools.ietf.org/html/rfc7231). @@ -61,121 +74,121 @@ But you can override the `message` and the `errorCode` to fit your for personal ### 400 Bad Request ```javascript -BadRequest(message, errorCode); +BadRequest(message?, errorCode?, originalError?); ``` ### 401 Unauthorized ```javascript -Unauthorized(message, errorCode); +Unauthorized(message?, errorCode?, originalError?); ``` ### 402 Payment Required ```javascript -PaymentRequired(message, errorCode); +PaymentRequired(message?, errorCode?, originalError?); ``` ### 403 Forbidden ```javascript -Forbidden(message, errorCode); +Forbidden(message?, errorCode?, originalError?); ``` ### 404 Not Found ```javascript -NotFound(message, errorCode); +NotFound(message?, errorCode?, originalError?); ``` ### 405 Method Not Allowed ```javascript -MethodNotAllowed(message, errorCode); +MethodNotAllowed(message?, errorCode?, originalError?); ``` ### 406 Not Acceptable ```javascript -NotAcceptable(message, errorCode); +NotAcceptable(message?, errorCode?, originalError?); ``` ### 407 Proxy Authentication Required ```javascript -ProxyAuthenticationRequired(message, errorCode); +ProxyAuthenticationRequired(message?, errorCode?, originalError?); ``` ### 408 Request Timeout ```javascript -RequestTimeout(message, errorCode); +RequestTimeout(message?, errorCode?, originalError?); ``` ### 409 Conflict ```javascript -Conflict(message, errorCode); +Conflict(message?, errorCode?, originalError?); ``` ### 410 Gone ```javascript -Gone(message, errorCode); +Gone(message?, errorCode?, originalError?); ``` ### 422 Unprocessable Entity ```javascript -UnprocessableEntity(message, errorCode); +UnprocessableEntity(message?, errorCode?, originalError?); ``` ### 424 Failed Dependency ```javascript -FailedDependency(message, errorCode); +FailedDependency(message?, errorCode?, originalError?); ``` ### 500 Internal Server Error ```javascript -InternalServerError(message, errorCode); +InternalServerError(message?, errorCode?, originalError?); ``` ### 501 Not Implemented ```javascript -NotImplemented(message, errorCode); +NotImplemented(message?, errorCode?, originalError?); ``` ### 502 Bad Gateway ```javascript -BadGateway(message, errorCode); +BadGateway(message?, errorCode?, originalError?); ``` ### 503 Service Unavailable ```javascript -ServiceUnavailable(message, errorCode); +ServiceUnavailable(message?, errorCode?, originalError?); ``` ### 504 Gateway Timeout ```javascript -GatewayTimeout(message, errorCode); +GatewayTimeout(message?, errorCode?, originalError?); ``` ### 505 HTTP Version Not Supported ```javascript -HttpVersionNotSupported(message, errorCode); +HttpVersionNotSupported(message?, errorCode?, originalError?); ``` ### 511 Network Authentication Required ```javascript -NetworkAuthenticationRequired(message, errorCode); +NetworkAuthenticationRequired(message?, errorCode?, originalError?); ``` ## TODO diff --git a/lib/CustomError.ts b/lib/CustomError.ts index bea81d0..9834f31 100644 --- a/lib/CustomError.ts +++ b/lib/CustomError.ts @@ -1,11 +1,13 @@ -export default class ExtendableError extends Error { +export default class CustomError extends Error { errorCode: number; statusCode: number; + originalError?: Error; constructor( message: string, statusCode: number = 400, - errorCode: number = 400 + errorCode: number = 400, + originalError?: Error ) { super(message); @@ -13,6 +15,7 @@ export default class ExtendableError extends Error { this.message = message; this.statusCode = statusCode; this.errorCode = errorCode; + this.originalError = originalError; if (typeof Error.captureStackTrace === "function") { Error.captureStackTrace(this, this.constructor); diff --git a/lib/errors/BadGateway.ts b/lib/errors/BadGateway.ts index 14ab39b..7a50430 100644 --- a/lib/errors/BadGateway.ts +++ b/lib/errors/BadGateway.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class BadGateway extends ExtendableError { - constructor(message: string = "Bad Gateway", errorCode: number = 502) { - super(message, 502, errorCode); + constructor( + message: string = "Bad Gateway", + errorCode: number = 502, + originalError?: Error + ) { + super(message, 502, errorCode, originalError); } } diff --git a/lib/errors/BadRequest.ts b/lib/errors/BadRequest.ts index 45bbc3a..613ba70 100644 --- a/lib/errors/BadRequest.ts +++ b/lib/errors/BadRequest.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class BadRequest extends ExtendableError { - constructor(message: string = "Bad Request", errorCode: number = 400) { - super(message, 400, errorCode); + constructor( + message: string = "Bad Request", + errorCode: number = 400, + originalError?: Error + ) { + super(message, 400, errorCode, originalError); } } diff --git a/lib/errors/Conflict.ts b/lib/errors/Conflict.ts index 71f9f3d..8656457 100644 --- a/lib/errors/Conflict.ts +++ b/lib/errors/Conflict.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class Conflict extends ExtendableError { - constructor(message: string = "Conflict", errorCode: number = 409) { - super(message, 409, errorCode); + constructor( + message: string = "Conflict", + errorCode: number = 409, + originalError?: Error + ) { + super(message, 409, errorCode, originalError); } } diff --git a/lib/errors/FailedDependency.ts b/lib/errors/FailedDependency.ts index 8e048b8..37f2135 100644 --- a/lib/errors/FailedDependency.ts +++ b/lib/errors/FailedDependency.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class FailedDependency extends ExtendableError { - constructor(message: string = "Failed Dependency", errorCode: number = 424) { - super(message, 424, errorCode); + constructor( + message: string = "Failed Dependency", + errorCode: number = 424, + originalError?: Error + ) { + super(message, 424, errorCode, originalError); } } diff --git a/lib/errors/Forbidden.ts b/lib/errors/Forbidden.ts index 0410313..ff930fb 100644 --- a/lib/errors/Forbidden.ts +++ b/lib/errors/Forbidden.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class Forbidden extends ExtendableError { - constructor(message: string = "Forbiden", errorCode: number = 403) { - super(message, 403, errorCode); + constructor( + message: string = "Forbiden", + errorCode: number = 403, + originalError?: Error + ) { + super(message, 403, errorCode, originalError); } } diff --git a/lib/errors/GatewayTimeout.ts b/lib/errors/GatewayTimeout.ts index f5d7c90..ed3a3f3 100644 --- a/lib/errors/GatewayTimeout.ts +++ b/lib/errors/GatewayTimeout.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class GatewayTimeout extends ExtendableError { - constructor(message: string = "Gateway Timeout", errorCode: number = 504) { - super(message, 504, errorCode); + constructor( + message: string = "Gateway Timeout", + errorCode: number = 504, + originalError?: Error + ) { + super(message, 504, errorCode, originalError); } } diff --git a/lib/errors/Gone.ts b/lib/errors/Gone.ts index 29fdc46..f544939 100644 --- a/lib/errors/Gone.ts +++ b/lib/errors/Gone.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class Gone extends ExtendableError { - constructor(message: string = "Gone", errorCode: number = 410) { - super(message, 410, errorCode); + constructor( + message: string = "Gone", + errorCode: number = 410, + originalError?: Error + ) { + super(message, 410, errorCode, originalError); } } diff --git a/lib/errors/HttpVersionNotSupported.ts b/lib/errors/HttpVersionNotSupported.ts index 1fae527..e098758 100644 --- a/lib/errors/HttpVersionNotSupported.ts +++ b/lib/errors/HttpVersionNotSupported.ts @@ -3,8 +3,9 @@ import ExtendableError from "../CustomError"; export default class HttpVersionNotSupported extends ExtendableError { constructor( message: string = "HTTP Version Not Supported", - errorCode: number = 505 + errorCode: number = 505, + originalError?: Error ) { - super(message, 505, errorCode); + super(message, 505, errorCode, originalError); } } diff --git a/lib/errors/InternalServerError.ts b/lib/errors/InternalServerError.ts index d053e58..ea9ca77 100644 --- a/lib/errors/InternalServerError.ts +++ b/lib/errors/InternalServerError.ts @@ -3,8 +3,9 @@ import ExtendableError from "../CustomError"; export default class InternalServerError extends ExtendableError { constructor( message: string = "Internal Server Error", - errorCode: number = 500 + errorCode: number = 500, + originalError?: Error ) { - super(message, 500, errorCode); + super(message, 500, errorCode, originalError); } } diff --git a/lib/errors/MethodNotAllowed.ts b/lib/errors/MethodNotAllowed.ts index 7f2ea50..59ed24d 100644 --- a/lib/errors/MethodNotAllowed.ts +++ b/lib/errors/MethodNotAllowed.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class MethodNotAllowed extends ExtendableError { - constructor(message: string = "Method Not Allowed", errorCode: number = 405) { - super(message, 405, errorCode); + constructor( + message: string = "Method Not Allowed", + errorCode: number = 405, + originalError?: Error + ) { + super(message, 405, errorCode, originalError); } } diff --git a/lib/errors/NetworkAuthenticationRequired.ts b/lib/errors/NetworkAuthenticationRequired.ts index 43c868b..cbdaf2e 100644 --- a/lib/errors/NetworkAuthenticationRequired.ts +++ b/lib/errors/NetworkAuthenticationRequired.ts @@ -3,8 +3,9 @@ import ExtendableError from "../CustomError"; export default class NetworkAuthenticationRequired extends ExtendableError { constructor( message: string = "Network Authentication Required", - errorCode: number = 511 + errorCode: number = 511, + originalError?: Error ) { - super(message, 511, errorCode); + super(message, 511, errorCode, originalError); } } diff --git a/lib/errors/NotAcceptable.ts b/lib/errors/NotAcceptable.ts index caac6d1..e149905 100644 --- a/lib/errors/NotAcceptable.ts +++ b/lib/errors/NotAcceptable.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class NotAcceptable extends ExtendableError { - constructor(message: string = "Not Acceptable", errorCode: number = 406) { - super(message, 406, errorCode); + constructor( + message: string = "Not Acceptable", + errorCode: number = 406, + originalError?: Error + ) { + super(message, 406, errorCode, originalError); } } diff --git a/lib/errors/NotFound.ts b/lib/errors/NotFound.ts index 2d42031..3c252d2 100644 --- a/lib/errors/NotFound.ts +++ b/lib/errors/NotFound.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class NotFound extends ExtendableError { - constructor(message: string = "Not Found", errorCode: number = 404) { - super(message, 404, errorCode); + constructor( + message: string = "Not Found", + errorCode: number = 404, + originalError?: Error + ) { + super(message, 404, errorCode, originalError); } } diff --git a/lib/errors/NotImplemented.ts b/lib/errors/NotImplemented.ts index db90f60..6ff88af 100644 --- a/lib/errors/NotImplemented.ts +++ b/lib/errors/NotImplemented.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class NotImplemented extends ExtendableError { - constructor(message: string = "Not Implemented", errorCode: number = 501) { - super(message, 501, errorCode); + constructor( + message: string = "Not Implemented", + errorCode: number = 501, + originalError?: Error + ) { + super(message, 501, errorCode, originalError); } } diff --git a/lib/errors/PaymentRequired.ts b/lib/errors/PaymentRequired.ts index b7a3de4..3975bb5 100644 --- a/lib/errors/PaymentRequired.ts +++ b/lib/errors/PaymentRequired.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class PaymentRequired extends ExtendableError { - constructor(message: string = "Payment Required", errorCode: number = 402) { - super(message, 402, errorCode); + constructor( + message: string = "Payment Required", + errorCode: number = 402, + originalError?: Error + ) { + super(message, 402, errorCode, originalError); } } diff --git a/lib/errors/ProxyAuthenticationRequired.ts b/lib/errors/ProxyAuthenticationRequired.ts index 52bca90..6381c76 100644 --- a/lib/errors/ProxyAuthenticationRequired.ts +++ b/lib/errors/ProxyAuthenticationRequired.ts @@ -3,8 +3,9 @@ import ExtendableError from "../CustomError"; export default class ProxyAuthenticationRequired extends ExtendableError { constructor( message: string = "Proxy Authentication Required", - errorCode: number = 407 + errorCode: number = 407, + originalError?: Error ) { - super(message, 407, errorCode); + super(message, 407, errorCode, originalError); } } diff --git a/lib/errors/RequestTimeout.ts b/lib/errors/RequestTimeout.ts index ad6a8af..5a647f0 100644 --- a/lib/errors/RequestTimeout.ts +++ b/lib/errors/RequestTimeout.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class RequestTimeout extends ExtendableError { - constructor(message: string = "Request Timeout", errorCode: number = 408) { - super(message, 408, errorCode); + constructor( + message: string = "Request Timeout", + errorCode: number = 408, + originalError?: Error + ) { + super(message, 408, errorCode, originalError); } } diff --git a/lib/errors/ServiceUnavailable.ts b/lib/errors/ServiceUnavailable.ts index ea2025d..62de249 100644 --- a/lib/errors/ServiceUnavailable.ts +++ b/lib/errors/ServiceUnavailable.ts @@ -3,8 +3,9 @@ import ExtendableError from "../CustomError"; export default class ServiceUnavailable extends ExtendableError { constructor( message: string = "Service Unavailable", - errorCode: number = 503 + errorCode: number = 503, + originalError?: Error ) { - super(message, 503, errorCode); + super(message, 503, errorCode, originalError); } } diff --git a/lib/errors/Unauthorized.ts b/lib/errors/Unauthorized.ts index 9e5fbc5..4f9401f 100644 --- a/lib/errors/Unauthorized.ts +++ b/lib/errors/Unauthorized.ts @@ -1,7 +1,11 @@ import ExtendableError from "../CustomError"; export default class Unauthorized extends ExtendableError { - constructor(message: string = "Unauthorized", errorCode: number = 401) { - super(message, 401, errorCode); + constructor( + message: string = "Unauthorized", + errorCode: number = 401, + originalError?: Error + ) { + super(message, 401, errorCode, originalError); } } diff --git a/lib/errors/UnprocessableEntity.ts b/lib/errors/UnprocessableEntity.ts index 66c1929..34844ce 100644 --- a/lib/errors/UnprocessableEntity.ts +++ b/lib/errors/UnprocessableEntity.ts @@ -3,8 +3,9 @@ import ExtendableError from "../CustomError"; export default class UnprocessableEntity extends ExtendableError { constructor( message: string = "Unprocessable Entity", - errorCode: number = 422 + errorCode: number = 422, + originalError?: Error ) { - super(message, 422, errorCode); + super(message, 422, errorCode, originalError); } } diff --git a/package.json b/package.json index 2945069..3a72c2d 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "A full REST API error collection", "scripts": { "build": "tsc", - "test": "ts-node ./tests/*.spec.ts" + "test": "for file in ./tests/*.spec.ts; do ts-node $file; done" }, "repository": { "type": "git", diff --git a/tests/CustomError.spec.ts b/tests/CustomError.spec.ts index 3043042..d0a9223 100644 --- a/tests/CustomError.spec.ts +++ b/tests/CustomError.spec.ts @@ -2,7 +2,8 @@ import * as assert from "assert"; import CustomError from "../lib/CustomError"; function doSomethingBad() { - throw new CustomError("CustomError", "It went bad!", 400, 400); + const originalError = new Error("Original error"); + throw new CustomError("It went bad!", 400, 4000, originalError); } try { @@ -17,6 +18,8 @@ try { // The error should be an instance of builtin Error assert(err instanceof Error); + assert(err.originalError instanceof Error); + // The error should be recognized by Node.js' util#isError assert(require("util").isError(err));