Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "http-error-kit",
"version": "1.0.0",
"version": "1.1.0",
"description": "A flexible and customizable error-handling library for HTTP applications. Provides structured error responses with optional formatters, predefined HTTP errors, and extensible error types.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -9,6 +9,16 @@
"./generic": "./dist/general.error.js",
"./http": "./dist/http.error.js"
},
"typesVersions": {
"*": {
"generic": [
"./dist/general.error.d.ts"
],
"http": [
"./dist/http.error.d.ts"
]
}
},
"scripts": {
"test": "jest --config jest.config.ts",
"build": "tsc --build",
Expand Down
30 changes: 30 additions & 0 deletions src/general.error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
CODES as STATUS_CODES,
getStatusDescription,
} from "http-response-status-code";
import { IRawInput } from "./interfaces/input.interface";

/**
* Represents a general error with a status code, message, and optional details.
Expand All @@ -26,6 +27,13 @@ export class KitGeneralError extends Error {
*/
details: unknown;

/**
* The raw input data associated with this instance.
* @private
* @type {IRawInput}
*/
private rawInputs: IRawInput;

/**
* Initializes a new instance of the KitGeneralError class.
* @param {number} statusCode - The HTTP status code associated with the error.
Expand All @@ -38,6 +46,28 @@ export class KitGeneralError extends Error {
this.statusCode = statusCode;
this.message = message.toString();
this.details = details;
this.rawInputs = { statusCode, message, details, args: [] };
Object.setPrototypeOf(this, KitGeneralError.prototype);
}

/**
* Returns the raw input data associated with this instance.
* @returns {IRawInput} The raw input data associated with this instance.
*/
getInputs() {
return this.rawInputs;
}

/**
* Returns a JSON-compatible object representation of this instance.
* @returns {{statusCode: number, message: string, details: unknown}} A JSON-compatible object representation of this instance.
*/
toJSON() {
return {
statusCode: this.statusCode,
message: this.message,
details: this.details,
};
}
}

Expand Down
33 changes: 33 additions & 0 deletions src/http.error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,39 @@ export class KitHttpError extends Error {

return this;
}

/**
* Returns the raw input data associated with this instance.
* @returns {IRawInput} The raw input data associated with this instance.
*/
getInputs() {
return this.rawInputs;
}

/**
* Returns a JSON-compatible object representation of this instance.
* If a formatter function is provided (either globally or instance-specific),
* it will be used to format the error details.
* Otherwise, the object will contain the `statusCode`, `message`, and `details` properties.
* @returns {{statusCode: number, message: string, details: unknown}} A JSON-compatible object representation of this instance.
*/
toJSON() {
const formatter =
this.instanceFormatter ?? KitHttpError.defaultFormatter;
if (formatter) {
return formatter(
this.rawInputs.statusCode,
this.rawInputs.message,
this.rawInputs.details,
...this.rawInputs.args
);
}
return {
statusCode: this.rawInputs.statusCode,
message: this.rawInputs.message,
details: this.rawInputs.details,
};
}
}

/**
Expand Down
24 changes: 24 additions & 0 deletions test/general.error.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,30 @@ describe("*** Testing KitGeneralError ***", function () {
expect(test instanceof KitGeneralError);
expect(test.message).toBe("Testing KitGeneralError");
});
it("Should return raw inputs", function () {
const test = new KitGeneralError(
STATUS_CODES.CODES.HTTP_CODE_400,
"Testing KitGeneralError"
);
const rawInputs = test.getInputs();
expect(test instanceof KitGeneralError);
expect(typeof rawInputs).toBe("object");
expect(rawInputs.statusCode).toBe(STATUS_CODES.CODES.HTTP_CODE_400);
expect(rawInputs.message).toBe("Testing KitGeneralError");
expect(rawInputs.details).toBe(undefined);
});
it("Should return proper serialized inputs", function () {
const test = new KitGeneralError(
STATUS_CODES.CODES.HTTP_CODE_400,
"Testing KitGeneralError"
);
const json = JSON.parse(JSON.stringify(test));
expect(test instanceof KitGeneralError);
expect(typeof json).toBe("object");
expect(json.statusCode).toBe(STATUS_CODES.CODES.HTTP_CODE_400);
expect(json.message).toBe("Testing KitGeneralError");
expect(json.details).toBe(undefined);
});
});

describe("*** Testing BadRequestError ***", function () {
Expand Down
80 changes: 80 additions & 0 deletions test/http.error.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,39 @@ describe("*** Testing KitHttpError ***", function () {
expect(error.msg).toBe("Testing KitHttpError");
expect(error.details).toEqual({});
});
it("Should return raw inputs with additional arguments", function () {
const test = new KitHttpError(
STATUS_CODES.HTTP_CODE_400,
"Testing KitHttpError",
{},
"argument1",
"argument2"
);
const rawInputs = test.getInputs();
expect(test instanceof KitHttpError);
expect(typeof rawInputs).toBe("object");
expect(rawInputs.statusCode).toBe(STATUS_CODES.HTTP_CODE_400);
expect(rawInputs.message).toBe("Testing KitHttpError");
expect(rawInputs.details).toStrictEqual({});
expect(rawInputs.args).toBeInstanceOf(Array);
expect(rawInputs.args).toEqual(["argument1", "argument2"]);
});
it("Should return proper serialized inputs", function () {
const test = new KitHttpError(
STATUS_CODES.HTTP_CODE_400,
"Testing KitHttpError",
{},
"argument1",
"argument2"
);
const json = JSON.parse(JSON.stringify(test));
console.log(json);
expect(test instanceof KitHttpError);
expect(typeof json).toBe("object");
expect(json.statusCode).toBe(STATUS_CODES.HTTP_CODE_400);
expect(json.message).toBe("Testing KitHttpError");
expect(json.details).toStrictEqual({});
});
});

describe("*** Testing KitHttpErrorConfig ***", function () {
Expand All @@ -1185,6 +1218,11 @@ describe("*** Testing KitHttpErrorConfig ***", function () {

describe("*** Testing KitHttpError with global formatter ***", function () {
it("Should be an instance of KitHttpError when no formatter is provided", function () {
KitHttpErrorConfig.configureFormatter(
(statusCode, message, details, ...args) => ({
list: args,
})
);
const error = new KitHttpError(
STATUS_CODES.HTTP_CODE_400,
"Testing KitHttpError",
Expand All @@ -1194,4 +1232,46 @@ describe("*** Testing KitHttpError with global formatter ***", function () {
expect(error instanceof KitHttpError);
expect(error.list).toEqual(["kit2"]);
});
it("Should return raw inputs", function () {
KitHttpErrorConfig.configureFormatter(() => {});
const test = new KitHttpError(
STATUS_CODES.HTTP_CODE_400,
"Testing KitHttpError"
);
const rawInputs = test.getInputs();
expect(test instanceof KitHttpError);
expect(typeof rawInputs).toBe("object");
expect(rawInputs.statusCode).toBe(STATUS_CODES.HTTP_CODE_400);
expect(rawInputs.message).toBe("Testing KitHttpError");
expect(rawInputs.details).toBe(undefined);
expect(rawInputs.args).toStrictEqual([]);
});
it("Should return proper serialized inputs", function () {
KitHttpErrorConfig.configureFormatter(
(statusCode, message, details, ...args) => {
return {
code: statusCode,
msg: message,
det: details,
arg1: args[0],
arg2: args[1],
};
}
);
const test = new KitHttpError(
STATUS_CODES.HTTP_CODE_400,
"Testing KitHttpError",
{},
"argument1",
"argument2"
);
const json = JSON.parse(JSON.stringify(test));
expect(test instanceof KitHttpError);
expect(typeof json).toBe("object");
expect(json.code).toBe(STATUS_CODES.HTTP_CODE_400);
expect(json.msg).toBe("Testing KitHttpError");
expect(json.det).toStrictEqual({});
expect(json.arg1).toBe("argument1");
expect(json.arg2).toBe("argument2");
});
});
7 changes: 5 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@
"module": "CommonJS" /* Specify what module code is generated. */,
"rootDir": "./src" /* Specify the root folder within your source files. */,
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
"baseUrl": "./" /* Specify the base directory to resolve non-relative module names. */,
"paths": {
"http-error-kit/generic": ["./dist/general.error.js"],
"http-error-kit/http": ["./dist/http.error.js"]
} /* Specify a set of entries that re-map imports to additional lookup locations. */,
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
Expand Down