---
title: "Capturing Errors"
description: "Learn how to use the Sentry JavaScript SDK to manually capture errors and other events."
url: https://docs.sentry.io/platforms/javascript/guides/effect/usage/
---

# Capturing Errors for Effect

Sentry's SDK hooks into your runtime environment and automatically reports errors, uncaught exceptions, and unhandled rejections as well as other types of errors depending on the platform.

Key terms:

* An *event* is one instance of sending data to Sentry. Generally, this data is an error or exception.
* An *issue* is a grouping of similar events.
* The reporting of an event is called *capturing*. When an event is captured, it's sent to Sentry.

The most common form of capturing is to capture errors. What can be captured as an error varies by platform. In general, if you have something that looks like an exception, it can be captured. For some SDKs, you can also omit the argument to `captureException` and Sentry will attempt to capture the current exception. It is also useful for manual reporting of errors or messages to Sentry.

While capturing an event, you can also record the breadcrumbs that lead up to that event. Breadcrumbs are different from events: they will not create an event in Sentry, but will be buffered until the next event is sent. Learn more about breadcrumbs in our [Breadcrumbs documentation](https://docs.sentry.io/platforms/javascript/guides/effect/enriching-events/breadcrumbs.md).

## [Capturing Errors](https://docs.sentry.io/platforms/javascript/guides/effect/usage.md#capturing-errors)

In Effect, a failure is a value in the error channel, not a thrown exception, so `try`/`catch` never sees it. How you capture failures depends on your Effect version.

### [Effect v3](https://docs.sentry.io/platforms/javascript/guides/effect/usage.md#effect-v3)

Effect v3 has no `ErrorReporter` API. To capture a failure, call `captureException()` inside `Effect.sync` from `Effect.tapError`. `tapError` doesn't recover from the failure, so the rest of your program handles it as before:

```typescript
import * as Sentry from "@sentry/effect";
import { Effect } from "effect";

const loadUser = (id: string) =>
  Effect.fail(new Error(`User ${id} could not be loaded`));

const program = loadUser("42").pipe(
  Effect.tapError((error) =>
    Effect.sync(() => Sentry.captureException(error)),
  ),
);
```

`tapError` only sees typed failures, such as the ones from `Effect.fail`. To also capture defects, such as an exception thrown inside `Effect.sync`, use `Effect.tapErrorCause` and pass `Cause.squash(cause)` to `captureException()`.

### [Effect v4](https://docs.sentry.io/platforms/javascript/guides/effect/usage.md#effect-v4)

Available since: `v10.75.0`

On Effect v4, `Sentry.effectLayer` registers a Sentry `ErrorReporter`, so you don't call `captureException()` yourself. Sentry captures every failure that Effect reports:

* Failures that pass through `Effect.withErrorReporting`
* Causes that you pass to `ErrorReporter.report`
* Failures at the reporting boundaries of Effect's HTTP and RPC servers, for example a route handler that fails

To report a failure in your own code, add `Effect.withErrorReporting`. It reports typed failures and defects, and it doesn't recover from them, so the rest of your program handles the failure as before.

Add it before any operator that recovers from the failure, such as `Effect.catch`, because Effect doesn't report a recovered failure. To report only defects, use `Effect.withErrorReporting({ defectsOnly: true })`.

```typescript
import { Effect } from "effect";

const loadUser = (id: string) =>
  Effect.fail(new Error(`User ${id} could not be loaded`));

const program = loadUser("42").pipe(Effect.withErrorReporting);
```

Sentry doesn't capture interruptions, and it captures an error that passes through more than one boundary only once. On the server, `effectLayer` also enables `contextLinesIntegration` and `linkedErrorsIntegration` by default, so these events include source context and the errors of their `cause` chain.

#### [Control How Errors Are Reported](https://docs.sentry.io/platforms/javascript/guides/effect/usage.md#control-how-errors-are-reported)

Add Effect's `ErrorReporter` annotations to your error classes to change the Sentry event:

* `ErrorReporter.ignore`: Set to `true` to skip expected failures, such as a missing record.
* `ErrorReporter.severity`: Sets the event level. For example, `"Warn"` becomes `warning` and `"Fatal"` becomes `fatal`. Errors without this annotation get the level `error`.
* `ErrorReporter.attributes`: Adds key-value pairs to the event as extra data.

```typescript
import { Data, ErrorReporter } from "effect";

class NotFoundError extends Data.TaggedError("NotFoundError")<{
  readonly id: string;
}> {
  // Not sent to Sentry
  readonly [ErrorReporter.ignore] = true;
}

class RateLimitError extends Data.TaggedError("RateLimitError")<{
  readonly retryAfter: number;
}> {
  // Sent with the level `warning` and `retryAfter` as extra data
  readonly [ErrorReporter.severity] = "Warn" as const;
  readonly [ErrorReporter.attributes] = { retryAfter: this.retryAfter };
}
```

If you register your own reporters with `ErrorReporter.layer`, pass `mergeWithExisting: true`. Without it, your reporters replace all reporters registered before them, which can include the Sentry reporter.

```typescript
import { ErrorReporter } from "effect";

const ConsoleReporterLive = ErrorReporter.layer(
  [ErrorReporter.make(({ error }) => console.error(error))],
  { mergeWithExisting: true },
);
```

## [Capturing Messages](https://docs.sentry.io/platforms/javascript/guides/effect/usage.md#capturing-messages)

Another common operation is to capture a bare message. A message is textual information that should be sent to Sentry. Typically, our SDKs don't automatically capture messages, but you can capture them manually.

Messages show up as issues on your issue stream, with the message as the issue name.

```javascript
Sentry.captureMessage("Something went wrong");

// optionally specify the severity level:
// "fatal" | "error" | "warning" | "log" | "debug" | "info" (default)
Sentry.captureMessage("Something went wrong", "warning");
```
