Skip to content

Commit

Permalink
Merge pull request #4 from giraugh/feat/attempt-error-utils
Browse files Browse the repository at this point in the history
Utils for attempting ops and catching errors
  • Loading branch information
giraugh authored Apr 19, 2023
2 parents e62c921 + 1c75a62 commit bc7385f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/warm-toes-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@giraugh/tools": minor
---

Add utilities for attempting operations and catching errors
32 changes: 32 additions & 0 deletions lib/errors/attemptOrCatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Attempt to call a function returning either the result or an error if one occurs
* @param f the function to call
* @returns either the result of f or an error
*
* @example
* attemptOrCatch(() => { throw new Error() }) // returns error
* @example
* attemptOrCatch(() => 'hello') === 'hello'
*/
export const attemptOrCatch = <TErr extends Error, TReturn>(f: () => TReturn): TErr | TReturn => {
try {
return f()
} catch (err) {
return err as TErr
}
}


// Tests
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest

it('works for example 1', () => {
const err = new Error()
expect(attemptOrCatch(() => { throw err })).toBe(err)
})

it('works for example 2', () => {
expect(attemptOrCatch(() => 'hello')).toBe('hello')
})
}
36 changes: 36 additions & 0 deletions lib/errors/attemptOrElse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Attempt to call a function or call a handler if an error occurs.
* @param fnRes the function to call
* @param fnErr the handler to call if an error occurs
* @returns the result of fnRes if succesfull or the result of fnErr
* @note the type of the return is always the same regardless of if an error occurs
*
* @example
* attemptOrElse(() => { throw new Error() }, (err) => 'oh no') // returns 'oh no'
* @example
* attemptOrElse(() => 'hello', (err) => 'oh no') === 'hello'
* @example
* const isDebugEnv = attemptOrElse(() => process.env.NODE_ENV === 'debug', () => false)
*/
export const attemptOrElse = <TReturn, TError extends Error>(fnRes: () => TReturn, fnErr: (err: TError) => TReturn): TReturn => {
try {
return fnRes()
} catch (err) {
return fnErr(err as TError)
}
}


// Tests
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest

it('works for example 1', () => {
const err = new Error()
expect(attemptOrElse(() => { throw err }, () => 'oh no')).toEqual('oh no')
})

it('works for example 2', () => {
expect(attemptOrElse(() => 'hello', () => 'oh no')).toEqual('hello')
})
}
2 changes: 2 additions & 0 deletions lib/errors/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './expectOrThrow'
export * from './attemptOrCatch'
export * from './attemptOrElse'

0 comments on commit bc7385f

Please sign in to comment.