Skip to content

Commit

Permalink
♻️ Refactor(oh-my-error)!: Refactoring and adding mass of new feature…
Browse files Browse the repository at this point in the history
…s to prepare package to version `2.0.0`
  • Loading branch information
INeedJobToStartWork committed Oct 8, 2024
1 parent cf02f35 commit dd36974
Show file tree
Hide file tree
Showing 27 changed files with 770 additions and 218 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# oh-my-error

## 2.0.0-prerelease.0

### Major Changes

- Add new Error Types, New Functions and Features to current existing functions
- Add `statusCodes` enum.
- Refactored `MyError` => `myError`, currently it's error object handler before throw.
- Added new Feature to `myErrorWrapper` - Instant throw error, no need to use condition with `isError` to throw Error.
- Added `myErrorWrapperAsync` which is `myErrorWrapper` alternative for async functions.
- Refactored `TMyError` - renamed `TMyError` => `IMyError`, changed from `type` to `interface` and structure.
- Add new Error (Organism) Interfaces `IMyError`,`IMyErrorAPI`,`IMyErrorRateLimit`,`IMyErrorValidation`
- Add new Error (Atom) types
`TSeverity`,`TSeverity2`,`TErrorMessages`,`TErrorMessagesExt`,`TMyErrorList`,`TErrorList`,`TCauseError`,`TDetails`,`TBaseError`,`TBaseErrorExt`,`TValidationError`,`TApiError`,`TApiRateLimit`,

## 1.1.1

### Patch Changes
Expand Down
213 changes: 201 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,53 @@
![image](https://github.com/INeedJobToStartWork/MyError/assets/97305201/03fa3e50-af28-4345-a3f7-f84d091b4eb1)

<h1 align="center">MyError</h1>
<p align="center"><b>Very Clean Error Handler!</b></p>

<p align="center"><b>A Very Clean Error Handler!</b></p>
<div align="center">
<a >📗Tutorials (in soon)</a> |
<a >📘Docs (in soon)</a> |
<a href="">🏗️Contributing Guide</a>
</div>
<hr/>

Benefits:

- All Errors in one Place
- Easier in Maintaining code (No more `trycatches`)
-

## **Showcase**

```ts
// Make your life better

// Instead
let data;
try {
data = readFile("...path");
} catch {
throw Error("Cant Load File!");
}

// Do
const data = myErrorWrapper(readFile, Error("Cant Load File!"))("...path");
```

# 📜 List of Contest

- [Install](#install)
- [Types](#types)
- [Functions](#functions)
- [myErrorWrapper](#myErrorWrapper)
- [myErrorCatcher](#myErrorCatcher)
- [myErrorHandler](#myErrorHandler)
- [Objects](#Objects)
- [MyErrorList](#MyErrorList)
- [MyHandler](#MyHandler)
- [Sample of Code](#sample-of-code)
- [📜 List of Contest](#-list-of-contest)
- [Install](#install)
- [TLDR (Only Most Important!)](#tldr-only-most-important)
- [Functions](#functions)
- [Types](#types)
- [Functions](#functions-1)
- [myError `♻️ Refactored`](#myerror-️-refactored)
- [myErrorWrapper/Async `🎉 New feature!`](#myerrorwrapperasync--new-feature)
- [myErrorCatcher](#myerrorcatcher)
- [myErrorHandler](#myerrorhandler)
- [Types](#types-1)
- [TMyErrorList](#tmyerrorlist)
- [Error Templates (Interfaces)](#error-templates-interfaces)
- [Predefined elements for Functions (Atoms)](#predefined-elements-for-functions-atoms)

## Install

Expand All @@ -37,3 +68,161 @@ Yarn
```bash copy
yarn add oh-my-error
```

## TLDR (Only Most Important!)

### Functions

| Name | Description |
| ---------------------------------------------- | ------------------------------- |
| [myError](#myerror-️-refactored) | Handle with Error Object |
| [myErrorWrapper](#myerrorwrapper--new-feature) | `trycatch` wrapper one liner |
| [myErrorCatcher](#myerrorcatcher) | `promise` wrapper |
| [myErrorHandler](#myerrorhandler) | handle scenarios for each error |

### Types

**Error Templates**

| Name | Description |
| ------------------------------------------------- | --------------------------------------------------------------- |
| [TMyErrorList](#tmyerrorlist) `!important` | For creating list with errors in one place! |
| [IMyError](#error-templates-interfaces) | Basic Error |
| [IMyErrorAPI](#error-templates-interfaces) | Basic Error API |
| [IMyErrorRateLimit](#error-templates-interfaces) | [IMyErrorApi](#error-templates-interfaces) with RateLimit error |
| [IMyErrorValidation](#error-templates-interfaces) | [IMyError](error-templates-interfaces) with Validation error |

**[Rest Types for creating own Errors](#predefined-elements-for-functions-atoms)**

## Functions

### myError `♻️ Refactored`

Processes an error object, invoking functions with provided arguments

```ts
const MyErrorList = {
BLACKLISTED: {
name: "Black Listed Name",
hint: "Try use other one!",
message: (name: string) => `${name} is on black list!`
}
} as const satisfies TMyErrorList;

throw new myError(MyErrorList.BLACKLISTED, { message: ["nameInputed"] });
```

**Output**

```ts
{
name:"Black Listed Name",
hint:"Try use other one!",
message:"nameInputed is on black list!"
}
```

### myErrorWrapper/Async `🎉 New feature!`

`trycatch` wrapper with instant error thrower.

```ts
// Before
let data;
try {
data = readFile("path...");
} catch(){
throw new Error("Can't read file!");
}

// After

const [data,isError] = myErrorWrapper(readFile)("path...");
if(isError) throw new Error("Can't read file!")

// Or instant Error Throw

const data = myErrorWrapper(readFile,new Error("Can't read file!"))("path...");
```

### myErrorCatcher

`new Promise` wrapper.

```ts
const data = await myErrorCatcher(readFile)("path...").catch(() => {
// Code before crash...
throw new Error("Can't read file!");
});
```

### myErrorHandler

Execute Scenarios for an error!

```ts
const [data, isError] = myErrorWrapper(readFile)("./ReadThisFile");

const MyErrorHandlerList = {
FS001: () => {
// Do this code if throw this error
console.error("ERROR");
}
};
if (isError) await myErrorHandler(data.code, MyErrorHandlerList)();
```

## Types

### TMyErrorList

> [!IMPORTANT]
> Use `as const satisfies TMyErrorList` to work it properly. <br/> **Don't** forget about `const` because without this
> you not gonna get tips.
> [!TIP]
> You can add `satisfies ERRORTYPE` per error to have strict typing per error or just add
> `as const satisfies TMyErrorList<ERRORTYPE>` to have strict typing too!
```ts
const ErrorList = {
notFound: {
name: "Not Found",
code: "FS001",
message: { user: "File not found", dev: "The file you are trying to read does not exist" },
hint: (path: string) => `Check if the file exists at ${path}`
} satisfies IMyError,
cantRead: {
code: "FS002",
name: "Cant Read",
message: { user: "Can't read file", dev: "readFileSync throw error" },
hint: {
user: "Check if the file is not corrupted or permissions",
dev: "File is corrupted or has no permissions to be read"
}
}
} as const satisfies TMyErrorList;
```

### Error Templates (Interfaces)

There you can find ready error structures.

| Name | Description | Extends |
| ------------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------- |
| IMyError `new!` | Basic Error | - |
| IMyErrorAPI `new!` | Basic Error for an API error | [IMyError](#error-templates-interfaces), [TApiError](#predefined-elements-for-functions-atoms) |
| IMyErrorRateLimit `new!` | API error for RateLimit | [IMyError](#error-templates-interfaces), [TApiRateLimit](#predefined-elements-for-functions-atoms) |
| IMyErrorValidation `new!` | API error for Validation problems | [IMyError](#error-templates-interfaces), [TValidationError](#predefined-elements-for-functions-atoms) |

### Predefined elements for Functions (Atoms)

Short predefined types to easy creating own Error types!

| Name (Col1) | Name (Col2) | Name (Col3) |
| ------------------------ | ----------------------- | --------------------- |
| TSeverity `new!` | TSeverity2 `new!` | TErrorMessages `new!` |
| TErrorMessagesExt `new!` | TMyErrorList `new!` | TErrorList `new!` |
| TCauseError `new!` | TDetails `new!` | TBaseError `new!` |
| TBaseErrorExt `new!` | TValidationError `new!` | TApiError `new!` |
| TApiRateLimit `new!` | | |
40 changes: 0 additions & 40 deletions README.npm.md

This file was deleted.

2 changes: 1 addition & 1 deletion config/tsuprc/tsup.prod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default defineConfig({
{ from: "./package.json", to: "./package.json" },
{ from: "./.npmrc", to: "./.npmrc" },
{ from: "./.npmignore", to: "./.npmignore" },
{ from: "./README.npm.md", to: "./README.md" }
{ from: "./README.md", to: "./README.md" }
]
})
]
Expand Down
6 changes: 5 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ export default ineedj({
yaml: false,
ignoreGlobalFiles: { gitIgnore: true, basicIgnores: true }
}
}).removeRules("@typescript-eslint/no-throw-literal" /** Use custom Error */);
}).removeRules(
"@typescript-eslint/no-throw-literal" /** Use custom Error */,
"@EslintSecurity/detect-object-injection",
"MD010/no-hard-tabs"
);
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "oh-my-error",
"version": "1.1.1",
"version": "2.0.0-prerelease.0",
"private": true,
"description": "A simple error handler for nodejs",
"keywords": [
"error",
Expand Down
4 changes: 4 additions & 0 deletions src/functions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from "./myErrorCatcher";
export * from "./myErrorWrapper";
export * from "./myErrorHandler";
export * from "./myError";
59 changes: 59 additions & 0 deletions src/functions/myError.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* eslint-disable @EslintSonar/no-duplicate-string */
import { describe, it, expect } from "vitest";
import { myError } from "./myError";
import type { IMyError, TMyErrorList } from "@/types";

describe("[FUNCTION] myError", () => {
it("should return a basic error object", () => {
const errorObj: IMyError = {
name: "Test Error",
message: "This is a test error",
code: 500
};

const result = myError(errorObj);
expect(result).toEqual(errorObj);
});
it("Example from Function should pass", () => {
const MyErrorList = {
BLACKLISTED: {
name: "Black Listed Name",
hint: "Try use other one!",
message: (name: string) => `${name} is on black list!`
}
} as const satisfies TMyErrorList;

expect(myError(MyErrorList.BLACKLISTED, { message: ["nameInputed"] })).toEqual({
...MyErrorList.BLACKLISTED,
message: (() => MyErrorList.BLACKLISTED.message("nameInputed"))()
});
});
it("should return solved test", () => {
const errorObj = {
name: "Black Listed Name",
message: (name: string, idNumber: number) => `${name} with ${idNumber} is blacklisted!`,
code: 500
} as const satisfies IMyError;

const result = myError(errorObj, { message: ["BadName", 123] });
expect(result).toEqual({ ...errorObj, message: `BadName with 123 is blacklisted!` });
});
it("Should not overwrite current keys which are not functions", () => {
const errorObj = {
name: "Black Listed Name",
message: (name: string, idNumber: number) => `${name} with ${idNumber} is blacklisted!`,
code: 500
} as const satisfies IMyError;
const result = myError(errorObj, { message: ["BadName", 123] });
expect(result).toEqual({ ...errorObj, message: `BadName with 123 is blacklisted!` });
});
it("Should not add new keys", () => {
const errorObj = {
name: "Black Listed Name",
message: (name: string, idNumber: number) => `${name} with ${idNumber} is blacklisted!`,
code: 500
} as const satisfies IMyError;
const result = myError(errorObj, { message: ["BadName", 123], nonono: "lololo" });
expect(result).toEqual({ ...errorObj, message: `BadName with 123 is blacklisted!` });
});
});
Loading

0 comments on commit dd36974

Please sign in to comment.