Result & Errors
Massaman treats expected failure as data. A fallible operation returns a Result<T> so its caller can see and handle both outcomes without relying on an exception path.
The error parameter preserves specific Error types while defaulting to Error for existing Result<T> call sites. Thrown and rejected values still exist at unsafe boundaries; attempt, attemptAsync, and err normalize non-Error values before returning an Err.
Why it matters
Exceptions hide failure outside a function's return type. A Result makes failure visible, keeps it local to the data flow, and gives TypeScript a discriminated union to narrow.
This creates a clear boundary:
- unsafe code may throw or reject
attemptorattemptAsynccatches that outcome once- application code handles
OkandErras ordinary values
Core tools
AbortError and TimeoutError provide recognizable error types for cancellation and time limits. They can be carried by an Err like any other Error.
When to use it
Use Result when failure is expected and the caller can respond:
- parsing untrusted input
- reading files or configuration
- calling a network or storage boundary
- enforcing a domain rule that can reject a value
Construct ok and err in functions that model fallibility directly. Use attempt and attemptAsync around APIs that communicate failure by throwing or rejecting.
Typed errors
Use an Error intersection or interface when callers need to map expected failures to protocol behavior. err preserves that specific type instead of widening it to Error.
The payload must remain an Error, so stack traces, causes, and error-boundary behavior stay consistent. Passing a string, object, or other non-Error value to err still produces Err<Error>.
Complete example
The unsafe operation is isolated in parseConfig. Everything after it handles typed data, and every result variant is covered.
When not to use it
Do not wrap every branch in a Result.
- Use a domain union such as
User | NotFoundwhen both variants are normal outcomes. - Let programmer errors fail loudly; they are bugs, not recoverable domain values.
- Use
unwraponly where crashing is the intended policy, such as required boot configuration.
Result describes expected failure. It is not a replacement for every union or every exception.
Related reference
attemptandattemptAsyncok,err,isOk, andisErrunwrapandtoErrorAbortErrorandTimeoutError- Pattern Matching