Aller au contenu

SDK Flutter

Le SDK Pionne pour Flutter. Auto-capture les erreurs FlutterError, les exceptions async via Zone, et enrichit chaque event avec le contexte device.

pubspec.yaml
dependencies:
pionne_flutter: ^0.3.3
Fenêtre de terminal
flutter pub get
import 'package:flutter/material.dart';
import 'package:pionne_flutter/pionne_flutter.dart';
void main() {
Pionne.init(
token: 'pio_live_xxx',
release: '1.0.0',
environment: 'production',
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) => const MaterialApp(home: MyHome());
}
  • FlutterError.onError — erreurs du framework Flutter (build, layout, paint)
  • Zone runner (via runZonedGuarded) — exceptions Dart async non capturées
  • PlatformDispatcher.instance.onError (Flutter 3.3+) — erreurs côté Dart non capturées par Flutter

Les handlers Dart ne voient que les crashs de l’isolate Dart. Un crash natif détruit tout le process avant qu’aucun Dart ne tourne. Depuis 0.4.0, le SDK embarque du code natif iOS + Android qui les enregistre via l’OS et les rejoue en événements fatal au lancement suivant.

Activé par défaut. Pour désactiver :

Pionne.init(PionneOptions(
token: 'pio_live_…',
captureNativeCrashes: false,
));

Via MetricKit (MXCrashDiagnostic) :

  • NSException Objective-C / Swift — nom de l’exception + message composé sur iOS 17+ (ex. NSInvalidArgumentException)
  • SignauxSIGSEGV, SIGABRT, SIGBUS, SIGILL, SIGFPE, SIGTRAP
  • Kills mémoire (OOM) et terminations watchdog (0x8badf00d)
  • Call stack tree — frames système symbolisées par l’OS ; frames app sous forme binaryName 0xADDRESS

Via ActivityManager.getHistoricalProcessExitReasons() :

  • REASON_CRASH — exception JVM non catchée
  • REASON_CRASH_NATIVE — crash natif NDK (C/C++)
  • REASON_ANR — Application Not Responding (avec la trace ANR)
  • REASON_LOW_MEMORY — kill mémoire (OOM)

Les crashs natifs arrivent au lancement qui suit le crash (l’OS les livre post-mortem), avec mechanism.type = "native" et un tag native.source (metrickit sur iOS, app_exit sur Android).

  • Platform.operatingSystemios, android, linux, etc.
  • Platform.operatingSystemVersion — version OS
  • package_info_plus — version d’app, build number, package name (peer dep optionnelle)
  • device_info_plus — modèle, manufacturer (peer dep optionnelle)
try {
await fetchData();
} catch (error, stackTrace) {
await Pionne.captureException(
error,
stackTrace: stackTrace,
tags: {'feature': 'sync'},
contexts: {'sync': {'retry': 2}},
);
}
Pionne.init(token: '…', release: '…', environment: '…');
Pionne.captureException(error, stackTrace: stack, tags: {});
Pionne.captureMessage('Cache miss', level: PionneLevel.warning);
Pionne.setUser(id: 'user_42');
Pionne.setTags({'region': 'eu'});
Pionne.setEnabled(false);
Pionne.addBreadcrumb(category: 'navigation', message: '/checkout');
PlateformeStatut
iOSSupporté
AndroidSupporté
WebSupporté
macOSSupporté
WindowsSupporté
LinuxSupporté

Pionne peut afficher la ville/région/pays approximatif de l’utilisateur sur chaque event. Désactivé par défaut pour la vie privée.

Pionne.init(PionneOptions(
token: 'pio_live_xxx',
sendGeography: true, // ← opt-in
));

Au démarrage, un seul appel HTTP vers https://ipapi.co/json/ (timeout 4 s) résout contexts.geo = { city, region, country, country_code } qui est attaché à tous les events suivants. Aucune permission iOS/Android requise (pas de GPS, juste l’inverse-DNS de l’IP). Si le lookup échoue, le SDK continue sans géo.

Pour un fournisseur custom : geographyEndpoint: 'https://geo.tonapi.com/'.

Le package_name (par exemple com.tonapp.app) est auto-pinné côté serveur au premier event. Si ton token fuite et qu’il est utilisé depuis une autre app, les events sont rejetés.