-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add support for sync error handling and streamline build process
The latest version of the project includes support for synchronous error handling with `mightFailSync` and `makeMightFailSync` functions. These functions allow for handling errors in synchronous code execution. Additionally, a new `publish` script has been added to the `package.json` file to streamline the build and publish process. The library now officially supports both async and sync error handling for enhanced versatility in error management. The README has been updated to reflect this change and emphasize the flexibility of the library. The `Either.ts` file has also been updated to improve the type definitions for a clearer implementation. This version marks a significant upgrade to error handling capabilities within the project.
- Loading branch information
1 parent
9169e87
commit 3c6a463
Showing
9 changed files
with
267 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
## [0.3.0] - 2024-03-16 | ||
|
||
### Added | ||
- Support for synchronous error handling with `mightFailSync` and `makeMightFailSync` functions. | ||
- A new `publish` script in `package.json` to streamline the build and publish process. | ||
|
||
### Changed | ||
- The library now officially supports both async and sync error handling. This change is reflected in the README to emphasize the library's versatility in handling errors in different contexts. | ||
- Updated `Either.ts` to streamline the type definition for a more straightforward implementation. | ||
|
||
## [0.1] - [0.2] | ||
|
||
|
||
### Added | ||
- Initial support for async error handling with `mightFail` and `makeMightFail` functions. | ||
- Comprehensive documentation in the README, illustrating the use of the library with practical examples. | ||
- Implementation of the `Either` type to support the async error handling pattern. | ||
|
||
### Changed | ||
- Various internal improvements for better performance and reliability. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import Either from "./Either" | ||
import mightFail from "./mightFail" | ||
import makeMightFail from "./makeMightFail" | ||
import Either from "./Either"; | ||
import { mightFail, mightFailSync } from "./mightFail"; | ||
import { makeMightFail, makeMightFailSync } from "./makeMightFail"; | ||
|
||
export { Either, mightFail, makeMightFail } | ||
export { Either, mightFail, makeMightFail, mightFailSync, makeMightFailSync }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,87 @@ | ||
import Either from "./Either"; | ||
import mightFail from "./mightFail"; | ||
import {mightFail, mightFailSync} from "./mightFail"; | ||
|
||
/** | ||
* Utility type that unwraps a Promise type. If T is a Promise, it extracts the type the Promise resolves to. | ||
* Utility type that unwraps a Promise type. If T is a Promise, it extracts the type the Promise resolves to, | ||
* providing direct access to the underlying value type. | ||
* | ||
* @template T The type to be unwrapped if it's a Promise. | ||
*/ | ||
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T; | ||
|
||
/** | ||
* Wraps a promise-returning function in a function that returns an Either. This function takes a function | ||
* which returns a Promise, and returns a new function that when called, will return an Either. | ||
* Wraps a promise-returning function in another function that instead of returning a Promise directly, | ||
* returns a Promise that resolves with an Either. This allows for the handling of both resolved values and | ||
* errors in a consistent, functional way. | ||
* | ||
* @export | ||
* @template T The type of the function to be wrapped. | ||
* @param {T} func The function to be wrapped. | ||
* @return {(...funcArgs: Parameters<T>) => Either<UnwrapPromise<ReturnType<T>>>} | ||
* A new function that takes the same arguments as the original function, but returns an Either. | ||
* @template T The function type that returns a Promise. | ||
* @param {T} func - The async function to be wrapped. This function should return a Promise. | ||
* @return {Function} A new function that, when called, returns a Promise that resolves with an Either object. | ||
* The Either object contains either a 'result' with the resolved value of the original Promise, or an 'error' if the Promise was rejected. | ||
* | ||
* @example | ||
* // Example of wrapping an async function that might fail: | ||
* async function fetchData(url: string): Promise<string> { | ||
* const response = await fetch(url); | ||
* if (!response.ok) { | ||
* throw new Error('Network response was not ok'); | ||
* } | ||
* return response.text(); | ||
* } | ||
* | ||
* const safeFetchData = makeMightFail(fetchData); | ||
* const {error, result} = await safeFetchData('https://example.com'); | ||
* | ||
* if (error) { | ||
* console.error('Fetching failed:', error.message); | ||
* return | ||
* } | ||
* console.log('Fetched data:', result); | ||
*/ | ||
export default function makeMightFail< | ||
export function makeMightFail< | ||
T extends (...args: any[]) => Promise<any> | ||
>( | ||
func: T | ||
): (...funcArgs: Parameters<T>) => Either<UnwrapPromise<ReturnType<T>>> { | ||
): (...funcArgs: Parameters<T>) => Promise<Either<UnwrapPromise<ReturnType<T>>>> { | ||
return async (...args: Parameters<T>) => { | ||
const promise = func(...args); | ||
return mightFail(promise); | ||
}; | ||
} | ||
|
||
/** | ||
* Wraps a synchronous function that might throw an exception in another function that, | ||
* instead of throwing, returns an Either object. This object contains either a 'result' | ||
* with the value returned by the function if it executes successfully, or an 'error' if the function throws. | ||
* | ||
* @export | ||
* @template T The function type that might throw an error. | ||
* @param {T} func - The function to be wrapped. This function might throw an exception. | ||
* @return {Function} A new function that, when called, returns an Either object with either a 'result' or an 'error'. | ||
* | ||
* @example | ||
* // Example of wrapping a synchronous function that might throw an error: | ||
* function parseJSON(jsonString: string) { | ||
* return JSON.parse(jsonString); // This might throw | ||
* } | ||
* | ||
* const safeParseJSON = makeMightFailSync(parseJSON); | ||
* const {error, result} = safeParseJSON('{"valid": "json"}'); | ||
* | ||
* if (error) { | ||
* console.error('Parsing failed:', error); | ||
* return; | ||
* } | ||
* console.log('Parsed object:', result); | ||
*/ | ||
export function makeMightFailSync< | ||
T extends (...args: any[]) => any | ||
>( | ||
func: T | ||
): (...funcArgs: Parameters<T>) => Either<ReturnType<T>> { | ||
return (...args: Parameters<T>) => { | ||
const throwingFunction = () => func(...args); | ||
return mightFailSync(throwingFunction); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { expect, test } from "vitest" | ||
import { makeMightFailSync } from "../src/index" | ||
|
||
function somethingThatThrows(input: string) { | ||
if (!input) { | ||
throw new Error("error") | ||
} | ||
return {message: input} | ||
} | ||
|
||
|
||
test("success returns the response", async () => { | ||
const func = makeMightFailSync(somethingThatThrows) | ||
const {error, result} = await func("success") | ||
expect(error).toBe(undefined) | ||
expect(result!.message).toBe("success") | ||
}) | ||
|
||
test("fail with error returns the error", async () => { | ||
const func = makeMightFailSync(somethingThatThrows) | ||
const {error, result} = await func("") | ||
expect(result).toBe(undefined) | ||
expect(error?.message).toBe("error") | ||
}) | ||
|
||
test("fail without error returns an error", async () => { | ||
const reject = () => { | ||
throw "a fit" | ||
}; | ||
const func = makeMightFailSync(reject) | ||
const {error, result} = await func() | ||
expect(result).toBe(undefined) | ||
expect(error?.message).toBeTruthy() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { expect, test } from "vitest"; | ||
import { mightFailSync } from "../src/index"; | ||
|
||
function somethingThatThrows(input: string) { | ||
if (!input) { | ||
throw new Error("error"); | ||
} | ||
return { message: input }; | ||
} | ||
|
||
test("success returns the response", async () => { | ||
const { error, result } = mightFailSync(() => somethingThatThrows("success")); | ||
expect(error).toBe(undefined); | ||
expect(result?.message).toBe("success"); | ||
}); | ||
|
||
test("fail with error returns the error", async () => { | ||
const { error, result } = mightFailSync(() => somethingThatThrows("")); | ||
expect(result).toBe(undefined); | ||
expect(error?.message).toBe("error"); | ||
}); | ||
|
||
test("fail without error returns an error", async () => { | ||
const { error, result } = await mightFailSync(() => { | ||
throw "a fit"; | ||
}); | ||
expect(result).toBe(undefined); | ||
expect(error?.message).toBeTruthy(); | ||
}); |