Skip to main content

Overview

The fromPromise and fromSafePromise static methods convert Promises into ResultAsync instances.

Signatures

fromPromise

static fromPromise<T, E>(
  promise: PromiseLike<T>,
  errorFn: (e: unknown) => E
): ResultAsync<T, E>
promise
PromiseLike<T>
required
A Promise that may resolve or reject
errorFn
(e: unknown) => E
required
Function to map the rejection reason to a known error type

fromSafePromise

static fromSafePromise<T, E = never>(
  promise: PromiseLike<T>
): ResultAsync<T, E>
promise
PromiseLike<T>
required
A Promise that will never reject

Usage

Basic fromPromise usage

import { ResultAsync } from 'neverthrow'

const result = ResultAsync.fromPromise(
  fetch('/api/user/123').then(r => r.json()),
  (e) => new Error(`Fetch failed: ${e}`)
)

// result is ResultAsync<User, Error>

Type-safe error mapping

type ApiError = 
  | { type: 'NetworkError', message: string }
  | { type: 'ParseError', json: string }

const fetchUser = (id: number) => {
  return ResultAsync.fromPromise(
    fetch(`/api/users/${id}`).then(r => r.json()),
    (error): ApiError => {
      if (error instanceof TypeError) {
        return { type: 'NetworkError', message: error.message }
      }
      return { type: 'ParseError', json: String(error) }
    }
  )
}

Chaining after fromPromise

const result = await ResultAsync.fromPromise(
  fs.promises.readFile('data.json', 'utf-8'),
  (e) => `Failed to read file: ${e}`
)
  .andThen(content => {
    try {
      return ok(JSON.parse(content))
    } catch (e) {
      return err('Invalid JSON')
    }
  })
  .map(data => data.users)

fromSafePromise usage

// Promise that never rejects
const delay = (ms: number) => 
  new Promise(resolve => setTimeout(resolve, ms))

const result = await ResultAsync.fromSafePromise(delay(1000))
  .map(() => 'Done!')

// result is Ok('Done!')

Rate limiting with safe promises

const rateLimitedFetch = (url: string) => {
  const delayPromise = new Promise(resolve => 
    setTimeout(resolve, 100)
  )
  
  return ResultAsync.fromSafePromise(delayPromise)
    .andThen(() => 
      ResultAsync.fromPromise(
        fetch(url),
        (e) => new Error('Fetch failed')
      )
    )
}

When to use each

Use fromPromise when:

  • Working with third-party APIs that may reject
  • Fetching from network (fetch, axios)
  • File I/O operations
  • Database queries
  • Any Promise that might reject

Use fromSafePromise when:

  • Creating delays with setTimeout
  • Wrapping synchronous operations in Promises
  • Working with Promise.resolve()
  • You guarantee the Promise never rejects
Only use fromSafePromise when you are absolutely certain the Promise will never reject. If it does reject, it will crash your program!

Comparison

// fromPromise - safe, requires error handler
const safe = ResultAsync.fromPromise(
  mayReject(),
  (e) => `Error: ${e}`
)
// Type: ResultAsync<Data, string>

// fromSafePromise - no error handler needed
const unsafe = ResultAsync.fromSafePromise(
  neverRejects()
)
// Type: ResultAsync<Data, never>

Top-level exports

These methods are also available as standalone functions:
import { fromPromise, fromSafePromise } from 'neverthrow'

const result1 = fromPromise(fetch('/api'), (e) => String(e))
const result2 = fromSafePromise(Promise.resolve(42))

from-throwable

Wrap functions that might throw

Async Operations Guide

Working with async operations

Build docs developers (and LLMs) love