# .NET Error Tracking installation - Docs

1.  1

    ## Install the .NET SDK

    Required

    For ASP.NET Core projects, install the [PostHog.AspNetCore](/docs/libraries/dotnet.md) package:

    Terminal

    PostHog AI

    ```bash
    dotnet add package PostHog.AspNetCore
    ```

    For other .NET projects, such as console applications, MAUI, or Blazor, install the core `PostHog` package:

    Terminal

    PostHog AI

    ```bash
    dotnet add package PostHog
    ```

2.  2

    ## Configure PostHog

    Required

    For ASP.NET Core, add PostHog to your `Program.cs` file:

    C#

    PostHog AI

    ```csharp
    using PostHog;
    var builder = WebApplication.CreateBuilder(args);
    builder.AddPostHog();
    ```

    Configure your project token and host in `appsettings.json`:

    JSON

    PostHog AI

    ```json
    {
      "PostHog": {
        "ProjectToken": "<ph_project_token>",
        "HostUrl": "https://us.i.posthog.com"
      }
    }
    ```

    For non-ASP.NET Core projects, initialize the core client as a singleton:

    C#

    PostHog AI

    ```csharp
    using PostHog;
    public static readonly PostHogClient PostHog = new(new PostHogOptions {
        ProjectToken = "<ph_project_token>",
        HostUrl = new Uri("https://us.i.posthog.com"),
    });
    ```

    You can find your project token and instance address in the [project settings](https://app.posthog.com/project/settings) page in PostHog.

3.  3

    ## Capture exceptions

    Required

    The .NET SDK supports manual exception capture with `CaptureException`. It builds the `$exception` event for you, including exception type, message, stack frames, inner exceptions, aggregate exceptions, source context when available, and .NET runtime metadata.

    The examples below assume `posthog` is an `IPostHogClient` from dependency injection, or your singleton `PostHogClient`.

    C#

    PostHog AI

    ```csharp
    try
    {
        ProcessOrder(orderId);
    }
    catch (Exception exception)
    {
        posthog.CaptureException(exception, "user_distinct_id");
    }
    ```

    Pass additional properties to add request, tenant, or domain context to the exception:

    C#

    PostHog AI

    ```csharp
    try
    {
        ProcessOrder(orderId);
    }
    catch (Exception exception)
    {
        posthog.CaptureException(
            exception,
            "user_distinct_id",
            new Dictionary<string, object>
            {
                ["order_id"] = orderId,
                ["environment"] = "production",
            }
        );
    }
    ```

    You can also attach feature flag values to the exception event with a feature flag snapshot:

    C#

    PostHog AI

    ```csharp
    var flags = await posthog.EvaluateFlagsAsync("user_distinct_id");
    posthog.CaptureException(
        exception,
        "user_distinct_id",
        properties: null,
        groups: null,
        flags: flags
    );
    ```

    **Automatic capture**

    Automatic exception capture is not available in the .NET SDK yet. Wrap the code paths you want to monitor and call `CaptureException` from your exception handlers.

4.  4

    ## Capture ASP.NET Core request exceptions

    Recommended

    For ASP.NET Core apps, add middleware to capture unhandled request exceptions and then rethrow them so your existing error handling still runs:

    C#

    PostHog AI

    ```csharp
    using Microsoft.Extensions.DependencyInjection;
    using PostHog;
    app.Use(async (context, next) =>
    {
        try
        {
            await next();
        }
        catch (Exception exception)
        {
            var posthog = context.RequestServices.GetRequiredService<IPostHogClient>();
            var distinctId = context.User.Identity?.Name ?? context.TraceIdentifier;
            posthog.CaptureException(
                exception,
                distinctId,
                new Dictionary<string, object>
                {
                    ["$current_url"] = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}",
                    ["$request_method"] = context.Request.Method,
                    ["$pathname"] = context.Request.Path.ToString(),
                }
            );
            throw;
        }
    });
    ```

5.  ## Verify error tracking

    Recommended

    Trigger and capture a test exception to confirm events are being sent to PostHog. You should see it appear in the [Error Tracking](https://app.posthog.com/error_tracking) tab.

    C#

    PostHog AI

    ```csharp
    try
    {
        throw new InvalidOperationException("Test exception from .NET");
    }
    catch (Exception exception)
    {
        posthog.CaptureException(exception, "test_user");
        await posthog.FlushAsync();
    }
    ```

    For serverless environments, call `FlushAsync()` before the process exits so queued exception events are sent.

### Community questions

Ask a question

### Was this page useful?

HelpfulCould be better