Skip to content

catch() ​

Handle errors in the Futurable.

Syntax ​

typescript
futurable.catch<TResult>(
  onrejected: (reason: any) => TResult | PromiseLike<TResult>
): Futurable<T | TResult>

Parameters ​

onrejected ​

Function called when the Futurable is rejected. Receives the rejection reason and can return a fallback value or re-throw.

Return Value ​

A new Futurable that resolves with either the original value or the fallback from the error handler.

Description ​

The catch() method is inherited from Promise and works exactly the same way. It's syntactic sugar for .then(undefined, onrejected).

Use it to handle errors in Futurable chains.

Examples ​

Basic Error Handling ​

typescript
Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(error => {
    console.error('Failed:', error);
    return { default: 'data' };
  });

With Cancellation ​

typescript
const request = Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Request was cancelled');
    } else {
      console.error('Request failed:', error);
    }
    return null;
  });

// Cancel if needed
request.cancel();

Recovery Chain ​

typescript
Futurable.fetch('/api/primary')
  .catch(error => {
    console.log('Primary failed, trying backup');
    return fetch('/api/backup');
  })
  .then(res => res.json())
  .catch(error => {
    console.log('Both failed, using default');
    return DEFAULT_DATA;
  });

Re-throwing Errors ​

typescript
Futurable.fetch('/api/data')
  .catch(error => {
    // Log but re-throw
    console.error('Error:', error);
    throw error;
  })
  .catch(error => {
    // Handle the re-thrown error
    return fallbackData;
  });

Type-Specific Error Handling ​

typescript
Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(error => {
    if (error.name === 'SyntaxError') {
      console.error('Invalid JSON');
      return { error: 'Invalid response format' };
    }
    if (error.status === 404) {
      console.error('Not found');
      return { error: 'Resource not found' };
    }
    throw error; // Re-throw unknown errors
  });

Comparison with try-catch ​

typescript
// Using catch()
const data = await Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(error => {
    console.error(error);
    return DEFAULT_DATA;
  });

// Using try-catch
let data;
try {
  const res = await Futurable.fetch('/api/data');
  data = await res.json();
} catch (error) {
  console.error(error);
  data = DEFAULT_DATA;
}

With async/await ​

typescript
try {
  const data = await Futurable.fetch('/api/data')
    .then(res => res.json());
  console.log(data);
} catch (error) {
  // This catches errors from the entire chain
  console.error(error);
}

// Or use catch() directly
const data = await Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(error => DEFAULT_DATA);

Multiple Catch Handlers ​

typescript
Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(error => {
    // First catch - try to recover
    console.log('Attempting recovery');
    return fetchFromCache();
  })
  .catch(error => {
    // Second catch - final fallback
    console.log('Using default');
    return DEFAULT_DATA;
  });

Cancellation Errors ​

typescript
const request = Futurable.fetch('/api/data')
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Cancelled - this is expected');
      return null;
    }
    console.error('Real error:', error);
    throw error;
  });

request.cancel(); // Will trigger catch with AbortError

Best Practices ​

1. Always Handle Errors ​

typescript
// ✅ Good - errors are handled
Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(error => console.error(error));

// ❌ Bad - unhandled rejection
Futurable.fetch('/api/data')
  .then(res => res.json());
// No error handling!

2. Provide Fallback Values ​

typescript
// ✅ Good - provides fallback
const data = await Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(() => DEFAULT_DATA);

// ❌ Bad - returns undefined on error
const data = await Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(error => {
    console.error(error);
    // No return value
  });

3. Log Before Handling ​

typescript
// ✅ Good - log then handle
.catch(error => {
  console.error('Operation failed:', error);
  return fallbackValue;
})

// ❌ Bad - silent failure
.catch(() => fallbackValue)

Alternative: safe() ​

For a more explicit error handling pattern, consider using safe():

typescript
// Using catch()
const data = await Futurable.fetch('/api/data')
  .then(res => res.json())
  .catch(error => {
    console.error(error);
    return null;
  });

// Using safe()
const result = await Futurable.fetch('/api/data')
  .then(res => res.json())
  .safe();

if (result.success) {
  const data = result.data;
} else {
  console.error(result.error);
}

Notes ​

  • Shorthand for .then(undefined, onrejected)
  • Catches any error in the chain before it
  • Can return a fallback value or re-throw
  • Fully compatible with Promise API
  • Futurable remains cancellable after catch()
  • Handles both errors and rejections

See Also ​

Released under the MIT License.