> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sending errors

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

The observability plugin automatically sends errors to LaunchDarkly. You can also use `recordError` to manually send a custom error.

Details about each SDK's configuration are available in the SDK-specific sections below:

* [Client-side SDKs](#client-side-sdks)
* [Server-side SDKs](#server-side-sdks)

## Viewing errors and sourcemaps

You can display all errors sent to LaunchDarkly under **Errors** in the LaunchDarkly user interface. To learn more, read [Error monitoring](/docs/home/observability/errors).

If you are working with a client-side SDK and using the **Errors** page in LaunchDarkly to debug an error, a stack trace from the original file in your codebase can help you understand what is going wrong. To provide this, LaunchDarkly needs access to the symbol files from your codebase:

* For web JavaScript applications, send your sourcemaps to LaunchDarkly using the `ldcli sourcemaps upload` command in the LaunchDarkly CLI. To learn how, read [Use `ldcli` for uploading sourcemaps](/docs/home/getting-started/ldcli-commands#use-ldcli-for-uploading-sourcemaps).
* For mobile applications, upload your symbol files so LaunchDarkly can retrace obfuscated, minified, or compiled stack frames. To learn how, read [Use `ldcli` for uploading symbols](/docs/home/getting-started/ldcli-commands#use-ldcli-for-uploading-symbols).

## Client-side SDKs

This feature is available in the observability plugin for the following client-side SDKs:

* [iOS](#ios)
* [Android](#android)
* [Flutter](#flutter)
* [JavaScript](#javascript)
* [React Native](#react-native)
* [React Web](#react-web)
* [Vue](#vue)

### iOS

<Accordion title="Expand iOS code sample">
  You can use `recordError` to manually send a custom error:

  <CodeGroup>
    ```swift title="Record error" lines wrap theme={null}
    LDObserve.shared.recordLog(message: message, severity: .info, attributes: attributes)
    ```
  </CodeGroup>

  To learn more, read [`recordError`](https://github.com/launchdarkly/swift-launchdarkly-observability/blob/b792a5c153ea55b0bfd308af35cbd1e8203b30d8/Sources/ApplicationServices/ObservabilityService.swift#L36).
</Accordion>

### Android

<Accordion title="Expand Android code sample">
  You can use `recordError` to manually send a custom error:

  <CodeGroup>
    ```java title="Record error" lines wrap theme={null}
    LDObserve.recordError(error, attributes)
    ```
  </CodeGroup>

  The attributes argument is optional. To construct it, use `Attributes` from the [`@opentelemetry/api`](https://opentelemetry.io/docs/specs/semconv/general/attributes/).
</Accordion>

### Flutter

<Accordion title="Expand Flutter code sample">
  The observability plugin automatically captures uncaught errors through `runZonedGuarded` and `FlutterError.onError`. You can also use `LDObserve.recordException` to manually record an error:

  <CodeGroup>
    ```dart title="Record exception" lines wrap theme={null}
    try {
      // something that throws
    } catch (e, stack) {
      LDObserve.recordException(e, stackTrace: stack);
    }
    ```
  </CodeGroup>

  To automatically capture uncaught Flutter framework errors and zone errors, add the following to your `main` function:

  <CodeGroup>
    ```dart title="Automatic error capture" lines wrap theme={null}
    FlutterError.onError = (FlutterErrorDetails details) {
      LDObserve.recordException(details.exception, stackTrace: details.stack);
    };

    runZonedGuarded(
      () { runApp(const MyApp()); },
      (err, stack) => LDObserve.recordException(err, stackTrace: stack),
    );
    ```
  </CodeGroup>
</Accordion>

### JavaScript

<Accordion title="Expand JavaScript code sample">
  You can use `recordError` to manually send a custom error:

  <CodeGroup>
    ```js title="Record error" lines wrap theme={null}
    LDObserve.recordError(error, 'optional message', {
      component: 'ExampleComponent.tsx',
    });
    ```
  </CodeGroup>

  The message and payload arguments are optional. To learn more, read [`recordError`](https://launchdarkly.github.io/observability-sdk/packages/@launchdarkly/observability/interfaces/api_observe.Observe.html#recorderror).
</Accordion>

### React Native

<Accordion title="Expand React Native code sample">
  You can use `recordError` to manually send a custom error:

  <CodeGroup>
    ```js title="Record error" lines wrap theme={null}
    LDObserve.recordError(error, attributes, options);
    ```
  </CodeGroup>

  The attributes and options arguments are optional. To construct them, use `Attributes` and `OtelSpan` from the [`@opentelemetry/api`](https://opentelemetry.io/docs/specs/semconv/general/attributes/). To learn more, read [`recordError`](https://launchdarkly.github.io/observability-sdk/sdk/@launchdarkly/observability-react-native/interfaces/Observe.html#recorderror).
</Accordion>

### React Web

To send a custom error with the React Web SDK, follow the example for [JavaScript](#javascript).

### Vue

To send a custom error with the React Web SDK, follow the example for [JavaScript](#javascript).

## Server-side SDKs

This feature is available in the observability plugin for the following server-side SDKs:

* [.NET (server-side)](#net-server-side)
* [Go](#go)
* [Node.js (server-side)](#node-js-server-side)
* [Python](#python)
* [Ruby](#ruby)

### .NET (server-side)

<Accordion title="Expand .NET (server-side) code sample">
  Use `RecordError` to manually send a custom error.

  Here's how:

  <CodeGroup>
    ```csharp title="Record error" lines wrap theme={null}
    Observe.RecordException(exception, metadata)
    ```
  </CodeGroup>

  You can optionally pass an array of `attributes`, which may include any attributes. We recommend using [attributes from the OpenTelemetry specification](https://opentelemetry.io/docs/specs/semconv/general/attributes/). To learn more, read [`RecordLog`](https://launchdarkly.github.io/observability-sdk/sdk/@launchdarkly/observability-dotnet/api/LaunchDarkly.Observability.Observe.html#LaunchDarkly_Observability_Observe_RecordLog_System_String_Microsoft_Extensions_Logging_LogLevel_System_Collections_Generic_IDictionary_System_String_System_Object__).
</Accordion>

### Go

<Accordion title="Expand Go code sample">
  Use `RecordError` to manually record an error in the current span.

  Here's how:

  <CodeGroup>
    ```go title="Record error" lines wrap theme={null}
    ldobserve.RecordError(ctx, err)
    ```
  </CodeGroup>

  This function takes a Go `context.Context` and the error. You can optionally pass an array of additional [attributes from the OpenTelemetry specification](https://pkg.go.dev/go.opentelemetry.io/otel/attribute#KeyValue). To learn more, read [`RecordError`](https://pkg.go.dev/github.com/launchdarkly/observability-sdk/go#RecordError).
</Accordion>

### Node.js (server-side)

<Accordion title="Expand Node.js (server-side) code sample">
  Use `recordError` to manually send a custom error.

  Here's how:

  <CodeGroup>
    ```js title="Record error" lines wrap theme={null}
    LDObserve.recordError(
      error,
      secureSessionId,
      requestId,
      metadata,
      options
    });
    ```
  </CodeGroup>

  The `recordError` method automatically provides trace context propagation, so you can leave the `secureSessionId` and `requestId` undefined. Alternatively, you have the option to set their values, to assist with the context propagation. You can parse values for `secureSessionId` and `requestId` from the incoming request using [`LDObserve.parseHeaders()`](https://launchdarkly.github.io/observability-sdk/sdk/@launchdarkly/observability-node/interfaces/Observe.html#parseheaders).

  The optional `metadata` can include any [attributes from the OpenTelemetry specification](https://opentelemetry.io/docs/specs/semconv/general/attributes/). To learn more, read [`recordError`](https://launchdarkly.github.io/observability-sdk/sdk/@launchdarkly/observability-node/interfaces/Observe.html#recorderror).
</Accordion>

### Python

<Accordion title="Expand Python code sample">
  Use `record_exception` to manually send a custom error.

  Here's how:

  <CodeGroup>
    ```python title="Record exception" lines wrap theme={null}
    try:
      # your application may raise an error
    except Exception as e:
      observe.record_exception(e)
    ```
  </CodeGroup>

  Passing the `Exception` records the exception contents and stack trace. You can optionally pass an array of additional `Attributes`, which may include any [attributes from the OpenTelemetry specification](https://opentelemetry.io/docs/specs/semconv/general/attributes/). To learn more, read [`record_exception`](https://launchdarkly.github.io/observability-sdk/sdk/@launchdarkly/observability-python/ldobserve/observe.html#record_exception).
</Accordion>

### Ruby

<Accordion title="Expand Ruby code sample">
  The Ruby observability plugin automatically captures unhandled exceptions in Rails applications through its Rack middleware. You can also use `record_exception` to manually record an error.

  Here's how:

  <CodeGroup>
    ```ruby title="Record exception" lines wrap theme={null}
    begin
      perform_operation
    rescue StandardError => e
      LaunchDarklyObservability.record_exception(e, attributes: {
        'operation' => 'example'
      })
      raise
    end
    ```
  </CodeGroup>

  The `attributes` argument is optional. You can include any [attributes from the OpenTelemetry specification](https://opentelemetry.io/docs/specs/semconv/general/attributes/). In Rails controllers, you can also use the `record_launchdarkly_exception` helper method. To learn more, read the [Ruby observability plugin README](https://github.com/launchdarkly/observability-sdk/tree/main/sdk/%40launchdarkly/observability-ruby).
</Accordion>
