TypeScript-first async error handling utility with typed Result pattern
npm install ts-try-asyncTypeScript-first async error handling utility with typed Result pattern.
Convert thrown exceptions into typed, predictable result objects — no more try/catch blocks scattered everywhere.
``bash`
npm install ts-try-async
`typescript
import { tryAsync } from 'ts-try-async'
const result = await tryAsync(() => fetchUser(id))
if (result.success) {
console.log(result.result) // User object, fully typed
} else {
console.log(result.message) // Error message string
console.log(result.cause) // Original error for debugging
}
`
TypeScript automatically narrows the type — result.result only exists when success === true.
`typescript`
const result = await tryAsync(
() => fetchUser(id),
{
onError: (error, message) => {
// error: full Error object with stack trace
// message: normalized string
Sentry.captureException(error)
logger.error(message)
}
}
)
Wrap a function once, reuse everywhere:
`typescript
import { withTryAsync } from 'ts-try-async'
const safeFetchUser = withTryAsync(fetchUser)
const result = await safeFetchUser(id) // Returns AsyncResult
`
With options:
`typescript`
const safeFetchUser = withTryAsync(fetchUser, {
onError: (error) => Sentry.captureException(error)
})
Executes an async function and returns a result object.
| Parameter | Type | Description |
|-----------|------|-------------|
| fn | () => Promise | Async function to execute |options.onError
| | (error: unknown, message: string) => void | Optional error callback |
Wraps an async function to return AsyncResult instead of throwing.
| Parameter | Type | Description |
|-----------|------|-------------|
| fn | (...args: TArgs) => Promise | Async function to wrap |options.onError
| | (error: unknown, message: string) => void | Optional error callback |
`typescript
type AsyncResult
interface AsyncSuccess
success: true
result: T
}
interface AsyncError {
success: false
message: string
cause: unknown
}
interface TryAsyncOptions {
onError?: (error: unknown, message: string) => void
}
`
- Type-safe: Discriminated unions enable automatic type narrowing
- Predictable: Errors become data, not exceptions
- Minimal: Zero dependencies, ~50 lines of code
- Flexible: Access full error via cause or onError` callback
MIT