# throwError

```typescript
throwError(errorOrErrorFactory: (() => any) | any): Observable<never>
```

**Creates an Observable that immediately emits an error notification upon subscription.**

***

💡 **When should you use throwError vs. just throwing an error?**

In most cases within operator callbacks (like `map`, `tap`, `mergeMap`), you can simply use JavaScript's native `throw` statement since RxJS wraps these in try-catch blocks. Use `throwError()` specifically when you need to **return an Observable that errors** - particularly in operators like `switchMap`, `mergeMap`, or `concatMap` where an Observable is expected as the return value.

💡 **Factory function recommended**

As of RxJS 7+, pass a factory function `() => error` rather than the error directly. This creates the error at the moment of subscription, providing better stack traces: `throwError(() => new Error('message'))`.

***

## Why use throwError?

Think of `throwError` as your "error signal generator" - it creates an Observable that does nothing but immediately send out an error signal. It's like having a specialized alarm button: when you press it, it doesn't emit any values or complete normally, it just triggers the error path.

You'll reach for `throwError` when you're working in Observable pipelines where you need to return an Observable, but something has gone wrong and you want to propagate that error downstream. For instance, in a [conditional API call](#example-2-conditional-error-in-switchmap) where you validate input before making a request, or when [implementing retry logic](#example-3-using-throwerror-with-retry-strategy) where you want to signal specific failures.

Here's a key insight: while JavaScript's native `throw` statement works great inside operators like `map` or `tap`, `throwError()` shines when you're in operators that expect you to return an Observable - like `switchMap`, `mergeMap`, or inside a custom creation function. In those cases, just throwing would break the chain; you need to return an error Observable instead. It's the difference between throwing an error in your code versus constructing an Observable that represents an error state.

***

## Examples

### Example 1: Basic error emission

[StackBlitz](https://stackblitz.com/edit/typescript-5d3stz?file=index.ts\&devtoolsheight=100)

```typescript
import { throwError } from 'rxjs';

// Create an observable that immediately emits an error
const error$ = throwError(() => new Error('Something went wrong!'));

// Subscribe to see the error
error$.subscribe({
  next: val => console.log('Next:', val), // Won't be called
  error: err => console.error('Error caught:', err.message),
  complete: () => console.log('Complete!') // Won't be called
});

// Output: "Error caught: Something went wrong!"
```

### Example 2: Conditional error in switchMap

[StackBlitz](https://stackblitz.com/edit/typescript-oulg71yj?file=index.ts)

```typescript
import { of, throwError } from 'rxjs';
import { mergeMap, catchError } from 'rxjs/operators';

interface User {
  id: number;
  name: string;
}

// Simulate fetching user data
function fetchUser(id: number) {
  return of({ id, name: `User ${id}` });
}

// Validate user ID before fetching - handle errors per item
of(0, 5, -1, 10)
  .pipe(
    mergeMap((id) => {
      // Create the source observable based on validation
      const source$ =
        id <= 0
          ? throwError(() => new Error(`Invalid user ID: ${id}`))
          : fetchUser(id);

      // Handle errors for each item individually
      return source$.pipe(
        catchError((err) => {
          console.error('Caught:', err());
          // Provide fallback user for this item only
          return of({ id: 0, name: 'Guest User' } as User);
        })
      );
    })
  )
  .subscribe((user) => console.log('User:', user.name));

/* Output:
   Caught: Invalid user ID: 0
   User: Guest User
   User: User 5
   Caught: Invalid user ID: -1
   User: Guest User
   User: User 10
*/
```

### Example 3: Using throwError with retry strategy

[StackBlitz](https://stackblitz.com/edit/typescript-gtwzvj3b?file=index.ts)

```typescript
import { of, throwError, timer } from 'rxjs';
import { mergeMap, retry, tap } from 'rxjs/operators';

let attemptCount = 0;

// Simulate an unreliable API call
function unreliableApiCall() {
  attemptCount++;
  console.log(`API call attempt #${attemptCount}`);
  
  // Fail first 2 attempts, succeed on 3rd
  return attemptCount < 3
    ? throwError(() => new Error('Network timeout'))
    : of({ data: 'Success!' });
}

// Try the API call with retry logic
of(null).pipe(
  mergeMap(() => unreliableApiCall()),
  retry(2) // Retry up to 2 times on error
).subscribe({
  next: result => console.log('Result:', result.data),
  error: err => console.error('Final error:', err.message)
});

/* Output:
   API call attempt #1
   API call attempt #2
   API call attempt #3
   Result: Success!
*/
```

***

## Related Recipes

* [Smart Counter](https://www.learnrxjs.io/learn-rxjs/recipes/smartcounter)
* [HTTP Polling](https://www.learnrxjs.io/learn-rxjs/recipes/http-polling)

***

## Additional Resources

* [throwError](https://rxjs.dev/api/index/function/throwError) 📰 - Official docs
* [Error Handling in RxJS](https://blog.angular-university.io/rxjs-error-handling/) 📰 - Comprehensive guide

***

📁 **Source Code:** <https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/throwError.ts>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.learnrxjs.io/learn-rxjs/operators/creation/throw.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
