├── package.json ├── README.md ├── .gitignore ├── tsconfig.json ├── index.ts └── bun.lock /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bun-err", 3 | "module": "index.ts", 4 | "type": "module", 5 | "private": true, 6 | "devDependencies": { 7 | "@types/bun": "latest" 8 | }, 9 | "peerDependencies": { 10 | "typescript": "^5" 11 | } 12 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bun-err 2 | Handle errors with ease in Bun. 3 | 4 | ## Installation 5 | ```bash 6 | bun add github.com:phillip-england/bun-err 7 | ``` 8 | 9 | ## Usage 10 | ```ts 11 | const [val, noErr] = await go(async () => { 12 | return "Hello, Non-Existent, Error-Free World!"; 13 | }); 14 | 15 | const [_, someErr] = await go(async () => { 16 | throw new Error("Hello, Honest, Error-Prone World!") 17 | }); 18 | 19 | if (someErr) { 20 | console.log(someErr) 21 | } 22 | ``` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies (bun install) 2 | node_modules 3 | 4 | # output 5 | out 6 | dist 7 | *.tgz 8 | 9 | # code coverage 10 | coverage 11 | *.lcov 12 | 13 | # logs 14 | logs 15 | _.log 16 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 17 | 18 | # dotenv environment variable files 19 | .env 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | .env.local 24 | 25 | # caches 26 | .eslintcache 27 | .cache 28 | *.tsbuildinfo 29 | 30 | # IntelliJ based IDEs 31 | .idea 32 | 33 | # Finder (MacOS) folder config 34 | .DS_Store 35 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Environment setup & latest features 4 | "lib": ["esnext"], 5 | "target": "ESNext", 6 | "module": "ESNext", 7 | "moduleDetection": "force", 8 | "jsx": "react-jsx", 9 | "allowJs": true, 10 | 11 | // Bundler mode 12 | "moduleResolution": "bundler", 13 | "allowImportingTsExtensions": true, 14 | "verbatimModuleSyntax": true, 15 | "noEmit": true, 16 | 17 | // Best practices 18 | "strict": true, 19 | "skipLibCheck": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedIndexedAccess": true, 22 | 23 | // Some stricter flags (disabled by default) 24 | "noUnusedLocals": false, 25 | "noUnusedParameters": false, 26 | "noPropertyAccessFromIndexSignature": false 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | export type Result = { 2 | isOk(): this is Ok; 3 | isErr(): this is Err; 4 | unwrap(): T | Promise; 5 | unwrapErr(): Error; 6 | }; 7 | 8 | class Ok implements Result { 9 | constructor(private value: T | Promise) {} 10 | isOk(): this is Ok { 11 | return true; 12 | } 13 | isErr(): this is Err { 14 | return false; 15 | } 16 | unwrap(): T | Promise { 17 | return this.value; 18 | } 19 | unwrapErr(): Error { 20 | throw new Error("Called unwrapErr on Ok"); 21 | } 22 | } 23 | 24 | class Err implements Result { 25 | constructor(private error: Error) {} 26 | isOk(): this is Ok { 27 | return false; 28 | } 29 | isErr(): this is Err { 30 | return true; 31 | } 32 | unwrap(): T | Promise { 33 | throw this.error; 34 | } 35 | unwrapErr(): Error { 36 | return this.error; 37 | } 38 | } 39 | 40 | export const exit = { 41 | ok(value: T | Promise): Result { 42 | return new Ok(value); 43 | }, 44 | err(error: Error | string): Result { 45 | const errInstance = typeof error === 'string' ? new Error(error) : error; 46 | return new Err(errInstance); 47 | } 48 | }; -------------------------------------------------------------------------------- /bun.lock: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1, 3 | "workspaces": { 4 | "": { 5 | "name": "bun-err", 6 | "devDependencies": { 7 | "@types/bun": "latest", 8 | }, 9 | "peerDependencies": { 10 | "typescript": "^5", 11 | }, 12 | }, 13 | }, 14 | "packages": { 15 | "@types/bun": ["@types/bun@1.2.5", "", { "dependencies": { "bun-types": "1.2.5" } }, "sha512-w2OZTzrZTVtbnJew1pdFmgV99H0/L+Pvw+z1P67HaR18MHOzYnTYOi6qzErhK8HyT+DB782ADVPPE92Xu2/Opg=="], 16 | 17 | "@types/node": ["@types/node@22.13.10", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw=="], 18 | 19 | "@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="], 20 | 21 | "bun-types": ["bun-types@1.2.5", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-3oO6LVGGRRKI4kHINx5PIdIgnLRb7l/SprhzqXapmoYkFl5m4j6EvALvbDVuuBFaamB46Ap6HCUxIXNLCGy+tg=="], 22 | 23 | "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], 24 | 25 | "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], 26 | } 27 | } 28 | --------------------------------------------------------------------------------