apptracer_flutter 0.1.2
apptracer_flutter: ^0.1.2 copied to clipboard
Unofficial Flutter integration with Tracer (apptracer.ru): reports Dart errors, Flutter framework errors and breadcrumbs that the native Tracer SDKs cannot see on their own.
Changelog #
All notable changes to this package are documented here.
The format follows Keep a Changelog,
and this package adheres to Semantic Versioning.
While the version is below 1.0.0, a breaking change bumps the minor version,
as pub.flutter-io.cn expects.
Unreleased #
0.1.2 - 2026-09-02 #
Changed #
apptracer_flutter_iosis now required at^0.1.2rather than^0.1.1. On 2026-08-31 the vendor moved theOKTracerbinaries tonexus-external.vkteam.ruand took the old host down, so every SDK release before 1.5.2 fails to download.apptracer_flutter_ios0.1.2 is the version that requiresOKTracer >= 1.5.2; with the looser constraint an application that upgraded this package would keep its locked 0.1.1, whose floor still admits the versions that no longer exist. See that package's changelog for the migration step (pod update OKTracer).apptracer_flutter_androidis now required at^0.1.1rather than^0.1.0. 0.1.1 is the version that stopped applying the Kotlin Gradle Plugin, and with the looser constraint an application that upgraded this package kept its locked 0.1.0 — and with it Flutter's "plugins that apply Kotlin Gradle Plugin (KGP)" warning namingapptracer_flutter_android.
Removed #
- The
metadependency, which nothing used. The only annotation in this package is@visibleForTesting, and it arrives throughpackage:flutter/foundation.dart, which re-exports it — there is noimport 'package:meta/meta.dart'anywhere here. Resolution is unaffected:metastays in the lockfile as a transitive dependency of Flutter itself. What goes away is a^1.12.0constraint this package had no business stating.
0.1.1 - 2026-08-30 #
Added #
-
dart run apptracer_flutter:install_ios_dsym_phase, which adds the dSYM upload build phase toRunner.xcodeproj. On CocoaPods the podspec does this atpod install; an application on Swift Package Manager evaluates no podspec, so the step has to be run once by hand. The command findsapptracer_flutter_iosthrough the package config and runs the script that ships there, so nobody has to dig a path out of the pub cache. Running it again refreshes the existing phase instead of adding a second one.It needs Ruby with the
xcodeprojgem — the pair CocoaPods itself runs on — and says so when they are missing, along with the file to paste into Xcode instead.
Changed #
- Requires
apptracer_flutter_ios^0.1.1, which is where the script the new command runs became runnable as a command. Under^0.1.0a resolution could pick 0.1.0, where that file only defines a method, and the command would report success having done nothing.
0.1.0 - 2026-08-28 #
Added #
-
dart run apptracer_flutter:upload_symbols ios|web, which uploads iOS dSYMs and web source maps. Android needs none of it — the Gradle plugin does it during the build — and on iOS the vendor's Fastlane plugin does the same on archive; web had no tool at all. It reads the version frompubspec.yaml, takes the token from--tokenorTRACER_PLUGIN_TOKEN, and exits non-zero unless the server confirms, because an ingest that answers 200 to a body it did not understand cannot be trusted on the status code alone. No new dependency: the archive is built withdart:io's raw deflate rather thanpackage:archive, which would otherwise ship in every application. -
Initial release.
-
Tracer.initializeruns the application inside a guarded zone and callsappRunnerexactly once in every scenario, including disabled collection, a platform SDK that fails to start, and a platform with no implementation. -
Captures
FlutterError.onError,PlatformDispatcher.instance.onErrorand guarded-zone errors, chaining to any handler that was already installed and restoring it onstopCollection. -
Deduplicates an error object that reaches the integration through more than one route.
-
Breadcrumbs with a bounded buffer, mirrored into the native log buffer so that native crashes carry the trail too.
-
beforeSendandbeforeBreadcrumbhooks; a hook that throws is logged and ignored rather than losing the event. -
Custom keys, user id, and manual error reporting with
severityandissueKey. -
maxRawStackTraceLogBytesandmaxStackFramesbound what a pathological stack trace can do. Android's log buffer is circular and 64 KiB, so an unbounded trace would evict the whole breadcrumb trail; the verbatim text is truncated at a line boundary, keeping thebuild_idheader and the frames nearest the throw.
Changed #
- Android setup no longer asks for a line of manifest. The non-fatal rate limit
that
ru.apptracer.flutter.TracerApplicationused to carry is applied byapptracer_flutter_androiditself, at process start, so an application without anApplicationclass of its own gets 10 non-fatals per hour instead of the SDK's silent 8 per session with nothing to configure. Applications that do have one still override it, and still subclassTracerApplicationto keep the limit.
Fixed #
-
The verbatim stack trace now renders in Tracer's log table. The console scans the log for the next record marker in sequence —
#3after#2— and expects#0 timestamp | textwhere it finds one; a Dart stack trace hands it frame numbers that look exactly like that, so the table view showedMatch line errorand nothing else. Frame numbers in a readable trace are now written[0],[1]. An obfuscated AOT trace is untouched byte for byte, soflutter symbolizestill accepts it, and the console never mistook its#00-style frames for records anyway. -
Grouping on Android. Measured against a live Tracer project on 2026-08-26, Tracer keys a group on the top frame's class and method alone: a
StateErrorand aTimeoutExceptionthrown from two closures inside onebuildlanded in the same group. When the caller supplies noissueKey, one is now synthesised from the error type and the innermost named frame — the rule iOS already used, moved into Dart so both platforms share it. Neither file nor line goes into the key, so editing code does not scatter a group. -
The documentation said the package adds no device identifier of its own. That was never true of the web path: the implementation mints a UUID, keeps it in
localStorageunderapptracer_flutter.deviceIdand sends it asdeviceIdon every event, together with the page host, screen metrics and visibility state. The README anddocs/privacy.mdnow say what actually goes out, and namedeviceIdas the install identifier it is. Whether the ingest would take an event without it is left unclaimed — the server answers200to a malformed body, so its absence cannot be tested.