# errorgap for Flutter

See [index.md](./index.md) for API details and the placeholder values (`ERRORGAP_API_KEY`, `ERRORGAP_ENDPOINT`, `ERRORGAP_PROJECT_SLUG`).

SDK source: `github.com/errorgaphq/errorgap-flutter` · current version: `0.2.0`. Requires Dart 3.0+.

## Install

```yaml
dependencies:
  errorgap: ^0.2.0
```

## Configure

```dart
import 'package:errorgap/errorgap.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'dart:ui';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  Errorgap.init(ErrorgapConfiguration(
    endpoint:    'https://errorgap.example.com',
    projectSlug: 'your-project',
    apiKey:      const String.fromEnvironment('ERRORGAP_API_KEY'),
    environment: kReleaseMode ? 'production' : 'development',
    apmEnabled: true,
    logsEnabled: true,
    deviceInfo: <String, Object?>{
      'os_name': defaultTargetPlatform.toString(),
    },
  ));

  FlutterError.onError = (FlutterErrorDetails details) {
    Errorgap.notify(details.exception, stackTrace: details.stack);
    FlutterError.presentError(details);
  };

  PlatformDispatcher.instance.onError = (Object error, StackTrace stack) {
    Errorgap.notify(error, stackTrace: stack);
    return true;
  };

  runApp(const MyApp());
}
```

`FlutterError.onError` and `PlatformDispatcher.instance.onError` are wired explicitly so callers can compose with their existing handlers.

## APM and logs

Send normalized request timing and child spans:

```dart
await Errorgap.notifyTransaction(ErrorgapTransaction(
  method: 'POST',
  path: '/orders/{orderId}',
  statusCode: 201,
  durationMs: 125,
  spans: [
    ErrorgapSpan.database(
      'SELECT * FROM orders WHERE id = 42',
      durationMs: 12,
      file: 'lib/orders.dart',
      line: 30,
      function: 'Orders.load',
    ),
  ],
));

await Errorgap.trackJob('ReceiptJob', (spans) async {
  await generateReceipt();
});

final logger = Errorgap.logger(source: 'flutter.checkout');
await logger?.warning('payment gateway timeout');
```

APM and logs are opt-in. Configure `apmEnabled`, `apmSampleRate`,
`logsEnabled`, and `minimumLogLevel` before sending them. For Dart VM source
excerpts, configure `applicationPackages` and `packageSourceRoots`; Flutter web
and compiled mobile builds safely omit sources that are not present at runtime.

## Trigger a test error

```dart
ElevatedButton(
  onPressed: () => throw Exception('Errorgap test error'),
  child: const Text('Test Errorgap'),
)
```

## Verify

Run the verification curl from [index.md](./index.md), then tap the button and confirm the onboarding screen advances.
