From fdd5e8014bcde0278b74f78415024da4e23e1ea7 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 14:58:30 +0100 Subject: [PATCH 01/16] feat(hive): add internal logger for sentry_hive package Co-Authored-By: Claude Opus 4.5 --- packages/hive/lib/src/internal_logger.dart | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 packages/hive/lib/src/internal_logger.dart diff --git a/packages/hive/lib/src/internal_logger.dart b/packages/hive/lib/src/internal_logger.dart new file mode 100644 index 0000000000..0e3546ce8a --- /dev/null +++ b/packages/hive/lib/src/internal_logger.dart @@ -0,0 +1,6 @@ +import 'package:meta/meta.dart'; +import 'package:sentry/sentry.dart'; + +/// Internal logger for sentry_hive package. +@internal +const internalLogger = SentryInternalLogger('sentry_hive'); From 0d778182f0ee1916a8e72346f0fc5d5c31842d31 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:00:44 +0100 Subject: [PATCH 02/16] feat(hive): migrate SentrySpanHelper to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() - Add proper null checks with warning logs - Maintain both async and sync wrapper methods Co-Authored-By: Claude Opus 4.5 --- packages/hive/lib/src/sentry_span_helper.dart | 124 +++++++++--------- 1 file changed, 64 insertions(+), 60 deletions(-) diff --git a/packages/hive/lib/src/sentry_span_helper.dart b/packages/hive/lib/src/sentry_span_helper.dart index 3df56b248b..cdbfde3ccd 100644 --- a/packages/hive/lib/src/sentry_span_helper.dart +++ b/packages/hive/lib/src/sentry_span_helper.dart @@ -1,22 +1,21 @@ +// ignore_for_file: invalid_use_of_internal_member + import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; + +import 'internal_logger.dart'; import 'sentry_hive_impl.dart'; /// @nodoc @internal class SentrySpanHelper { - /// @nodoc - Hub _hub = HubAdapter(); - - /// @nodoc + final Hub _hub; final String _origin; + late final InstrumentationSpanFactory _factory; /// @nodoc - SentrySpanHelper(this._origin); - - /// @nodoc - void setHub(Hub hub) { - _hub = hub; + SentrySpanHelper(this._origin, {Hub? hub}) : _hub = hub ?? HubAdapter() { + _factory = _hub.options.spanFactory; } /// @nodoc @@ -26,50 +25,52 @@ class SentrySpanHelper { Future Function() execute, { String? dbName, }) async { - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild( + final parentSpan = _factory.getSpan(_hub); + if (parentSpan == null) { + internalLogger.warning( + 'No active span found. Skipping tracing for Hive operation: $description', + ); + return execute(); + } + + final span = _factory.createSpan( + parentSpan, SentryHiveImpl.dbOp, description: description, ); - // ignore: invalid_use_of_internal_member - span?.origin = _origin; + if (span == null) { + return execute(); + } + + span.origin = _origin; + span.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); + if (dbName != null) { + span.setData(SentryHiveImpl.dbNameKey, dbName); + } final breadcrumb = Breadcrumb( message: description, - data: {}, + data: { + SentryHiveImpl.dbSystemKey: SentryHiveImpl.dbSystem, + if (dbName != null) SentryHiveImpl.dbNameKey: dbName, + }, type: 'query', ); - span?.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); - if (dbName != null) { - span?.setData(SentryHiveImpl.dbNameKey, dbName); - } - - breadcrumb.data?[SentryHiveImpl.dbSystemKey] = SentryHiveImpl.dbSystem; - if (dbName != null) { - breadcrumb.data?[SentryHiveImpl.dbNameKey] = dbName; - } - try { final result = await execute(); - - span?.status = SpanStatus.ok(); + span.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; - return result; } catch (exception) { - span?.throwable = exception; - span?.status = SpanStatus.internalError(); - + span.throwable = exception; + span.status = SpanStatus.internalError(); breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; - rethrow; } finally { - await span?.finish(); - - // ignore: invalid_use_of_internal_member + await span.finish(); await _hub.scope.addBreadcrumb(breadcrumb); } } @@ -81,51 +82,54 @@ class SentrySpanHelper { T Function() execute, { String? dbName, }) { - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild( + final parentSpan = _factory.getSpan(_hub); + if (parentSpan == null) { + internalLogger.warning( + 'No active span found. Skipping tracing for Hive operation: $description', + ); + return execute(); + } + + final span = _factory.createSpan( + parentSpan, SentryHiveImpl.dbOp, description: description, ); - // ignore: invalid_use_of_internal_member - span?.origin = _origin; - span?.setData('sync', true); + if (span == null) { + return execute(); + } + + span.origin = _origin; + span.setData('sync', true); + span.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); + if (dbName != null) { + span.setData(SentryHiveImpl.dbNameKey, dbName); + } final breadcrumb = Breadcrumb( message: description, - data: {}, + data: { + SentryHiveImpl.dbSystemKey: SentryHiveImpl.dbSystem, + if (dbName != null) SentryHiveImpl.dbNameKey: dbName, + }, type: 'query', ); - span?.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); - if (dbName != null) { - span?.setData(SentryHiveImpl.dbNameKey, dbName); - } - - breadcrumb.data?[SentryHiveImpl.dbSystemKey] = SentryHiveImpl.dbSystem; - if (dbName != null) { - breadcrumb.data?[SentryHiveImpl.dbNameKey] = dbName; - } - try { final result = execute(); - - span?.status = SpanStatus.ok(); + span.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; - return result; } catch (exception) { - span?.throwable = exception; - span?.status = SpanStatus.internalError(); - + span.throwable = exception; + span.status = SpanStatus.internalError(); breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; - rethrow; } finally { - span?.finish(); - - // ignore: invalid_use_of_internal_member + // Fire-and-forget for sync operations + span.finish(); _hub.scope.addBreadcrumb(breadcrumb); } } From 35a5ff4fba466efe936eb42f1ed65674e1ed7974 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:05:29 +0100 Subject: [PATCH 03/16] feat(hive): update classes to use new SentrySpanHelper constructor - Pass Hub directly to SentrySpanHelper constructor - Remove setHub() method calls - Update tests to use constructor parameter Co-Authored-By: Claude Opus 4.5 --- packages/hive/lib/src/sentry_box.dart | 11 ++++---- packages/hive/lib/src/sentry_box_base.dart | 11 ++++---- .../hive/lib/src/sentry_box_collection.dart | 27 ++++++++----------- packages/hive/lib/src/sentry_hive_impl.dart | 21 ++++++++++----- packages/hive/lib/src/sentry_lazy_box.dart | 11 ++++---- .../hive/test/sentry_box_collection_test.dart | 4 +-- 6 files changed, 44 insertions(+), 41 deletions(-) diff --git a/packages/hive/lib/src/sentry_box.dart b/packages/hive/lib/src/sentry_box.dart index b3123cd792..ee107f1836 100644 --- a/packages/hive/lib/src/sentry_box.dart +++ b/packages/hive/lib/src/sentry_box.dart @@ -11,14 +11,15 @@ class SentryBox extends SentryBoxBase implements Box { final Box _box; final Hub _hub; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHiveBoxBase, - ); + late final SentrySpanHelper _spanHelper; /// @nodoc SentryBox(this._box, @internal this._hub) : super(_box, _hub) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHiveBoxBase, + hub: _hub, + ); } @override diff --git a/packages/hive/lib/src/sentry_box_base.dart b/packages/hive/lib/src/sentry_box_base.dart index df08118335..46798f2eda 100644 --- a/packages/hive/lib/src/sentry_box_base.dart +++ b/packages/hive/lib/src/sentry_box_base.dart @@ -9,14 +9,15 @@ class SentryBoxBase implements BoxBase { final BoxBase _boxBase; final Hub _hub; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHiveBoxBase, - ); + late final SentrySpanHelper _spanHelper; /// @nodoc SentryBoxBase(this._boxBase, this._hub) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHiveBoxBase, + hub: _hub, + ); } @override diff --git a/packages/hive/lib/src/sentry_box_collection.dart b/packages/hive/lib/src/sentry_box_collection.dart index 48f28f60f1..8503d7b9c3 100644 --- a/packages/hive/lib/src/sentry_box_collection.dart +++ b/packages/hive/lib/src/sentry_box_collection.dart @@ -6,7 +6,6 @@ import 'package:hive/src/box_collection/box_collection_stub.dart' as impl; // ignore: implementation_imports import 'package:hive/src/box_collection/box_collection_stub.dart' as stub; -import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; import 'sentry_span_helper.dart'; @@ -15,13 +14,16 @@ import 'sentry_span_helper.dart'; class SentryBoxCollection implements stub.BoxCollection { final impl.BoxCollection _boxCollection; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHiveBoxCollection, - ); + late final SentrySpanHelper _spanHelper; /// Init with [impl.BoxCollection] - SentryBoxCollection(this._boxCollection); + SentryBoxCollection(this._boxCollection, {Hub? hub}) { + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHiveBoxCollection, + hub: hub ?? HubAdapter(), + ); + } @override Set get boxNames => _boxCollection.boxNames; @@ -31,12 +33,6 @@ class SentryBoxCollection implements stub.BoxCollection { _boxCollection.close(); } - /// @nodoc - @internal - void setHub(Hub hub) { - _spanHelper.setHub(hub); - } - @override Future deleteFromDisk() { return _spanHelper.asyncWrapInSpan( @@ -59,11 +55,12 @@ class SentryBoxCollection implements stub.BoxCollection { HiveCipher? key, Hub? hub, }) async { + final resolvedHub = hub ?? HubAdapter(); final spanHelper = SentrySpanHelper( // ignore: invalid_use_of_internal_member SentryTraceOrigins.autoDbHiveBoxCollection, + hub: resolvedHub, ); - spanHelper.setHub(hub ?? HubAdapter()); return await spanHelper.asyncWrapInSpan( 'open', @@ -74,9 +71,7 @@ class SentryBoxCollection implements stub.BoxCollection { path: path, key: key, ); - final sbc = SentryBoxCollection(boxCollection); - sbc.setHub(hub ?? HubAdapter()); - return sbc; + return SentryBoxCollection(boxCollection, hub: resolvedHub); }, dbName: name, ); diff --git a/packages/hive/lib/src/sentry_hive_impl.dart b/packages/hive/lib/src/sentry_hive_impl.dart index 83e0e2234a..ceca7640ac 100644 --- a/packages/hive/lib/src/sentry_hive_impl.dart +++ b/packages/hive/lib/src/sentry_hive_impl.dart @@ -33,13 +33,16 @@ class SentryHiveImpl implements SentryHiveInterface { final HiveInterface _hive; Hub _hub = HubAdapter(); - /// @nodoc - SentryHiveImpl(this._hive); + late SentrySpanHelper _spanHelper; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHive, - ); + /// @nodoc + SentryHiveImpl(this._hive) { + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHive, + hub: _hub, + ); + } // SentryHiveInterface @@ -50,7 +53,11 @@ class SentryHiveImpl implements SentryHiveInterface { options.sdk.addIntegration('SentryHiveTracing'); options.sdk.addPackage(packageName, sdkVersion); _hub = hub; - _spanHelper.setHub(hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHive, + hub: hub, + ); } // HiveInterface diff --git a/packages/hive/lib/src/sentry_lazy_box.dart b/packages/hive/lib/src/sentry_lazy_box.dart index 86eabb9fdd..b6b33eb43f 100644 --- a/packages/hive/lib/src/sentry_lazy_box.dart +++ b/packages/hive/lib/src/sentry_lazy_box.dart @@ -11,14 +11,15 @@ class SentryLazyBox extends SentryBoxBase implements LazyBox { final LazyBox _lazyBox; final Hub _hub; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbHiveLazyBox, - ); + late final SentrySpanHelper _spanHelper; /// @nodoc SentryLazyBox(this._lazyBox, @internal this._hub) : super(_lazyBox, _hub) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbHiveLazyBox, + hub: _hub, + ); } @override diff --git a/packages/hive/test/sentry_box_collection_test.dart b/packages/hive/test/sentry_box_collection_test.dart index d62ebf6ffe..ef1af559b6 100644 --- a/packages/hive/test/sentry_box_collection_test.dart +++ b/packages/hive/test/sentry_box_collection_test.dart @@ -384,9 +384,7 @@ class Fixture { Future getSut({bool injectMock = false}) async { if (injectMock) { - final sbc = SentryBoxCollection(mockBoxCollection); - sbc.setHub(hub); - return sbc; + return SentryBoxCollection(mockBoxCollection, hub: hub); } else { return await SentryBoxCollection.open(dbName, {'people'}, hub: hub); } From 91d83df2a9f81815097b800e632489b93822c8f3 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:12:33 +0100 Subject: [PATCH 04/16] feat(file): migrate to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() - Maintain both async and sync wrapper methods Co-Authored-By: Claude Opus 4.5 --- packages/file/lib/src/sentry_file.dart | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/file/lib/src/sentry_file.dart b/packages/file/lib/src/sentry_file.dart index ec2d2c99f7..1463d2e8a1 100644 --- a/packages/file/lib/src/sentry_file.dart +++ b/packages/file/lib/src/sentry_file.dart @@ -239,12 +239,14 @@ class SentryFile implements File { this._file, { @internal Hub? hub, }) : _hub = hub ?? HubAdapter() { + _spanFactory = _hub.options.spanFactory; _hub.options.sdk.addIntegration('SentryFileTracing'); _hub.options.sdk.addPackage(packageName, sdkVersion); } final File _file; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; @override Future copy(String newPath) { @@ -421,8 +423,12 @@ class SentryFile implements File { Future _wrap(Callback callback, String operation) async { final desc = _getDesc(); - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild(operation, description: desc); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + operation, + description: desc, + ); span?.origin = SentryTraceOrigins.autoFile; span?.setData('file.async', true); @@ -484,8 +490,12 @@ class SentryFile implements File { T _wrapSync(Callback callback, String operation) { final desc = _getDesc(); - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild(operation, description: desc); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + operation, + description: desc, + ); span?.origin = SentryTraceOrigins.autoFile; span?.setData('file.async', false); @@ -533,6 +543,7 @@ class SentryFile implements File { span?.status = SpanStatus.internalError(); rethrow; } finally { + // Fire-and-forget for sync operations span?.finish(); _hub.addBreadcrumb( From 7e91988aa355207b5c9cc6fc364f07c71de26c94 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:14:46 +0100 Subject: [PATCH 05/16] feat(supabase): migrate to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() - Return InstrumentationSpan from _createSpan helper Co-Authored-By: Claude Opus 4.5 --- .../src/sentry_supabase_tracing_client.dart | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/supabase/lib/src/sentry_supabase_tracing_client.dart b/packages/supabase/lib/src/sentry_supabase_tracing_client.dart index 6aa5ebc365..f699d4366a 100644 --- a/packages/supabase/lib/src/sentry_supabase_tracing_client.dart +++ b/packages/supabase/lib/src/sentry_supabase_tracing_client.dart @@ -9,8 +9,11 @@ import 'sentry_supabase_request.dart'; class SentrySupabaseTracingClient extends BaseClient { final Client _innerClient; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; - SentrySupabaseTracingClient(this._innerClient, this._hub); + SentrySupabaseTracingClient(this._innerClient, this._hub) { + _spanFactory = _hub.options.spanFactory; + } @override Future send(BaseRequest request) async { @@ -56,9 +59,9 @@ class SentrySupabaseTracingClient extends BaseClient { // Helper - ISentrySpan? _createSpan(SentrySupabaseRequest supabaseRequest) { - final currentSpan = _hub.getSpan(); - if (currentSpan == null) { + InstrumentationSpan? _createSpan(SentrySupabaseRequest supabaseRequest) { + final parentSpan = _spanFactory.getSpan(_hub); + if (parentSpan == null) { _hub.options.log( SentryLevel.warning, 'Active Sentry transaction does not exist, could not start span for the Supabase operation: from(${supabaseRequest.table})', @@ -66,11 +69,17 @@ class SentrySupabaseTracingClient extends BaseClient { ); return null; } - final span = currentSpan.startChild( + + final span = _spanFactory.createSpan( + parentSpan, 'db.${supabaseRequest.operation.value}', description: 'from(${supabaseRequest.table})', ); + if (span == null) { + return null; + } + final dbSchema = supabaseRequest.request.headers['Accept-Profile'] ?? supabaseRequest.request.headers['Content-Profile']; if (dbSchema != null) { From ecd908efccb781f82e0c3363dd256ac27786c92d Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:17:32 +0100 Subject: [PATCH 06/16] feat(link): migrate SentryTracingLink to InstrumentationSpan - Use InstrumentationSpanFactory for child span creation - Keep legacy API for transaction creation (when shouldStartTransaction=true) - Wrap transactions in LegacyInstrumentationSpan for unified interface Co-Authored-By: Claude Opus 4.5 --- .../link/lib/src/sentry_tracing_link.dart | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/link/lib/src/sentry_tracing_link.dart b/packages/link/lib/src/sentry_tracing_link.dart index 93c420eed9..724c77f8f0 100644 --- a/packages/link/lib/src/sentry_tracing_link.dart +++ b/packages/link/lib/src/sentry_tracing_link.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_use_of_internal_member + import 'dart:async'; import 'package:gql_exec/gql_exec.dart'; @@ -18,9 +20,12 @@ class SentryTracingLink extends Link { required this.shouldStartTransaction, required this.graphQlErrorsMarkTransactionAsFailed, Hub? hub, - }) : _hub = hub ?? HubAdapter(); + }) : _hub = hub ?? HubAdapter() { + _spanFactory = _hub.options.spanFactory; + } final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; /// If [shouldStartTransaction] is set to true, a [SentryTransaction] /// is automatically created for each GraphQL query/mutation. @@ -44,7 +49,7 @@ class SentryTracingLink extends Link { final sentryOperation = operationType?.sentryOperation ?? 'unknown'; final sentryType = operationType?.sentryType; - final transaction = _startSpan( + final span = _startSpan( 'GraphQL: "${request.operation.operationName ?? 'unnamed'}" $sentryType', sentryOperation, shouldStartTransaction, @@ -53,9 +58,9 @@ class SentryTracingLink extends Link { handleData: (data, sink) { final hasGraphQlError = data.errors?.isNotEmpty ?? false; if (graphQlErrorsMarkTransactionAsFailed && hasGraphQlError) { - transaction?.finish(status: const SpanStatus.unknownError()); + unawaited(span?.finish(status: const SpanStatus.unknownError())); } else { - transaction?.finish(status: const SpanStatus.ok()); + unawaited(span?.finish(status: const SpanStatus.ok())); } sink.add(data); @@ -67,24 +72,27 @@ class SentryTracingLink extends Link { // The correct `SpanStatus` can be set on // `HttpLinkResponseContext.statusCode` or // `DioLinkResponseContext.statusCode` - transaction?.throwable = error; - unawaited(transaction?.finish(status: const SpanStatus.unknownError())); + span?.throwable = error; + unawaited(span?.finish(status: const SpanStatus.unknownError())); sink.addError(error, stackTrace); }, )); } - ISentrySpan? _startSpan( - String op, + InstrumentationSpan? _startSpan( String description, + String op, bool shouldStartTransaction, ) { - final span = _hub.getSpan(); - if (span == null && shouldStartTransaction) { - return _hub.startTransaction(description, op, bindToScope: true); - } else if (span != null) { - return span.startChild(op, description: description); + final parentSpan = _spanFactory.getSpan(_hub); + if (parentSpan == null && shouldStartTransaction) { + // Start a new transaction - InstrumentationSpan doesn't support this + // so we use the legacy API and wrap it + final transaction = _hub.startTransaction(description, op, bindToScope: true); + return LegacyInstrumentationSpan(transaction); + } else if (parentSpan != null) { + return _spanFactory.createSpan(parentSpan, op, description: description); } return null; } From 70bbd17a2020e1be703a66ac74b8a9c71daf2938 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:17:36 +0100 Subject: [PATCH 07/16] feat(link): migrate SentryRequestSerializer to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() Co-Authored-By: Claude Opus 4.5 --- .../lib/src/sentry_request_serializer.dart | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/link/lib/src/sentry_request_serializer.dart b/packages/link/lib/src/sentry_request_serializer.dart index 1d766bd900..4f656e262d 100644 --- a/packages/link/lib/src/sentry_request_serializer.dart +++ b/packages/link/lib/src/sentry_request_serializer.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_use_of_internal_member + import 'dart:async'; import 'package:gql_exec/gql_exec.dart'; @@ -7,17 +9,23 @@ import 'package:sentry/sentry.dart'; class SentryRequestSerializer implements RequestSerializer { SentryRequestSerializer({RequestSerializer? inner, Hub? hub}) : inner = inner ?? const RequestSerializer(), - _hub = hub ?? HubAdapter(); + _hub = hub ?? HubAdapter() { + _spanFactory = _hub.options.spanFactory; + } final RequestSerializer inner; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; @override Map serializeRequest(Request request) { - final span = _hub.getSpan()?.startChild( - 'serialize.http.client', - description: 'GraphGL request serialization', - ); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + 'serialize.http.client', + description: 'GraphGL request serialization', + ); + Map result; try { result = inner.serializeRequest(request); From 593b513bb0a4d06ebee43413883f322987755d3f Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:17:39 +0100 Subject: [PATCH 08/16] feat(link): migrate SentryResponseParser to InstrumentationSpan - Use InstrumentationSpanFactory instead of hub.getSpan()?.startChild() Co-Authored-By: Claude Opus 4.5 --- .../link/lib/src/sentry_response_parser.dart | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/link/lib/src/sentry_response_parser.dart b/packages/link/lib/src/sentry_response_parser.dart index ab02e7f46a..b391617bff 100644 --- a/packages/link/lib/src/sentry_response_parser.dart +++ b/packages/link/lib/src/sentry_response_parser.dart @@ -1,3 +1,5 @@ +// ignore_for_file: invalid_use_of_internal_member + import 'dart:async'; import 'package:gql_exec/gql_exec.dart'; @@ -7,18 +9,24 @@ import 'package:sentry/sentry.dart'; class SentryResponseParser implements ResponseParser { SentryResponseParser({ResponseParser? inner, Hub? hub}) : inner = inner ?? const ResponseParser(), - _hub = hub ?? HubAdapter(); + _hub = hub ?? HubAdapter() { + _spanFactory = _hub.options.spanFactory; + } final ResponseParser inner; final Hub _hub; + late final InstrumentationSpanFactory _spanFactory; @override Response parseResponse(Map body) { - final span = _hub.getSpan()?.startChild( - 'serialize.http.client', - description: 'Response deserialization ' - 'from JSON map to Response object', - ); + final parentSpan = _spanFactory.getSpan(_hub); + final span = _spanFactory.createSpan( + parentSpan, + 'serialize.http.client', + description: 'Response deserialization ' + 'from JSON map to Response object', + ); + Response result; try { result = inner.parseResponse(body); From 2c23bee402cf0b4eeaff5cbda011cb17bf084afe Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:23:44 +0100 Subject: [PATCH 09/16] Update --- packages/isar/lib/src/internal_logger.dart | 6 + packages/isar/lib/src/sentry_isar.dart | 19 +-- .../isar/lib/src/sentry_isar_collection.dart | 12 +- packages/isar/lib/src/sentry_span_helper.dart | 134 +++++++++--------- 4 files changed, 91 insertions(+), 80 deletions(-) create mode 100644 packages/isar/lib/src/internal_logger.dart diff --git a/packages/isar/lib/src/internal_logger.dart b/packages/isar/lib/src/internal_logger.dart new file mode 100644 index 0000000000..abb5ff37d6 --- /dev/null +++ b/packages/isar/lib/src/internal_logger.dart @@ -0,0 +1,6 @@ +import 'package:meta/meta.dart'; +import 'package:sentry/sentry.dart'; + +/// Internal logger for sentry_isar package. +@internal +const internalLogger = SentryInternalLogger('sentry_isar'); diff --git a/packages/isar/lib/src/sentry_isar.dart b/packages/isar/lib/src/sentry_isar.dart index 3d36bb58a5..7ea36613ca 100644 --- a/packages/isar/lib/src/sentry_isar.dart +++ b/packages/isar/lib/src/sentry_isar.dart @@ -30,14 +30,15 @@ class SentryIsar implements Isar { final Isar _isar; final Hub _hub; - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbIsar, - ); + late final SentrySpanHelper _spanHelper; /// ctor of SentryIsar SentryIsar(this._isar, this._hub) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbIsar, + hub: _hub, + ); // ignore: invalid_use_of_internal_member final options = _hub.options; @@ -56,12 +57,12 @@ class SentryIsar implements Isar { bool inspector = true, Hub? hub, }) async { + final hubToUse = hub ?? HubAdapter(); final spanHelper = SentrySpanHelper( // ignore: invalid_use_of_internal_member SentryTraceOrigins.autoDbIsar, + hub: hubToUse, ); - final hubToUse = hub ?? HubAdapter(); - spanHelper.setHub(hubToUse); final isar = await spanHelper.asyncWrapInSpan( 'open', @@ -93,12 +94,12 @@ class SentryIsar implements Isar { bool inspector = true, Hub? hub, }) { + final hubToUse = hub ?? HubAdapter(); final spanHelper = SentrySpanHelper( // ignore: invalid_use_of_internal_member SentryTraceOrigins.autoDbIsar, + hub: hubToUse, ); - final hubToUse = hub ?? HubAdapter(); - spanHelper.setHub(hubToUse); final isar = spanHelper.syncWrapInSpan( 'openSync', diff --git a/packages/isar/lib/src/sentry_isar_collection.dart b/packages/isar/lib/src/sentry_isar_collection.dart index d79dfb8bb7..6d9ec28608 100644 --- a/packages/isar/lib/src/sentry_isar_collection.dart +++ b/packages/isar/lib/src/sentry_isar_collection.dart @@ -11,15 +11,15 @@ class SentryIsarCollection implements IsarCollection { final IsarCollection _isarCollection; final Hub _hub; final String _dbName; - - final _spanHelper = SentrySpanHelper( - // ignore: invalid_use_of_internal_member - SentryTraceOrigins.autoDbIsarCollection, - ); + late final SentrySpanHelper _spanHelper; /// ctor of SentryIsarCollection SentryIsarCollection(this._isarCollection, this._hub, this._dbName) { - _spanHelper.setHub(_hub); + _spanHelper = SentrySpanHelper( + // ignore: invalid_use_of_internal_member + SentryTraceOrigins.autoDbIsarCollection, + hub: _hub, + ); } @override diff --git a/packages/isar/lib/src/sentry_span_helper.dart b/packages/isar/lib/src/sentry_span_helper.dart index 50624b300a..59c4752218 100644 --- a/packages/isar/lib/src/sentry_span_helper.dart +++ b/packages/isar/lib/src/sentry_span_helper.dart @@ -1,24 +1,21 @@ -// ignore_for_file: invalid_internal_annotation +// ignore_for_file: invalid_use_of_internal_member import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; + +import 'internal_logger.dart'; import 'sentry_isar.dart'; /// @nodoc @internal class SentrySpanHelper { - /// @nodoc - Hub _hub = HubAdapter(); - - /// @nodoc + final Hub _hub; final String _origin; + late final InstrumentationSpanFactory _factory; /// @nodoc - SentrySpanHelper(this._origin); - - /// @nodoc - void setHub(Hub hub) { - _hub = hub; + SentrySpanHelper(this._origin, {Hub? hub}) : _hub = hub ?? HubAdapter() { + _factory = _hub.options.spanFactory; } /// @nodoc @@ -29,52 +26,55 @@ class SentrySpanHelper { String? dbName, String? collectionName, }) async { - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild( + final parentSpan = _factory.getSpan(_hub); + if (parentSpan == null) { + internalLogger.warning( + 'No active span found. Skipping tracing for Isar operation: $description', + ); + return execute(); + } + + final span = _factory.createSpan( + parentSpan, SentryIsar.dbOp, description: description, ); - // ignore: invalid_use_of_internal_member - span?.origin = _origin; - - final breadcrumb = Breadcrumb( - message: description, - data: {}, - type: 'query', - ); - - span?.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); + if (span == null) { + return execute(); + } + span.origin = _origin; + span.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); if (dbName != null) { - span?.setData(SentryIsar.dbNameKey, dbName); - breadcrumb.data?[SentryIsar.dbNameKey] = dbName; + span.setData(SentryIsar.dbNameKey, dbName); } - if (collectionName != null) { - span?.setData(SentryIsar.dbCollectionKey, collectionName); - breadcrumb.data?[SentryIsar.dbCollectionKey] = collectionName; + span.setData(SentryIsar.dbCollectionKey, collectionName); } + final breadcrumb = Breadcrumb( + message: description, + data: { + if (dbName != null) SentryIsar.dbNameKey: dbName, + if (collectionName != null) SentryIsar.dbCollectionKey: collectionName, + }, + type: 'query', + ); + try { final result = await execute(); - - span?.status = SpanStatus.ok(); + span.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; - return result; } catch (exception) { - span?.throwable = exception; - span?.status = SpanStatus.internalError(); - + span.throwable = exception; + span.status = SpanStatus.internalError(); breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; - rethrow; } finally { - await span?.finish(); - - // ignore: invalid_use_of_internal_member + await span.finish(); await _hub.scope.addBreadcrumb(breadcrumb); } } @@ -87,53 +87,57 @@ class SentrySpanHelper { String? dbName, String? collectionName, }) { - final currentSpan = _hub.getSpan(); - final span = currentSpan?.startChild( + final parentSpan = _factory.getSpan(_hub); + if (parentSpan == null) { + internalLogger.warning( + 'No active span found. Skipping tracing for Isar operation: $description', + ); + return execute(); + } + + final span = _factory.createSpan( + parentSpan, SentryIsar.dbOp, description: description, ); - // ignore: invalid_use_of_internal_member - span?.origin = _origin; - span?.setData('sync', true); - - final breadcrumb = Breadcrumb( - message: description, - data: {}, - type: 'query', - ); - - span?.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); + if (span == null) { + return execute(); + } + span.origin = _origin; + span.setData('sync', true); + span.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); if (dbName != null) { - span?.setData(SentryIsar.dbNameKey, dbName); - breadcrumb.data?[SentryIsar.dbNameKey] = dbName; + span.setData(SentryIsar.dbNameKey, dbName); } - if (collectionName != null) { - span?.setData(SentryIsar.dbCollectionKey, collectionName); - breadcrumb.data?[SentryIsar.dbCollectionKey] = collectionName; + span.setData(SentryIsar.dbCollectionKey, collectionName); } + final breadcrumb = Breadcrumb( + message: description, + data: { + if (dbName != null) SentryIsar.dbNameKey: dbName, + if (collectionName != null) SentryIsar.dbCollectionKey: collectionName, + }, + type: 'query', + ); + try { final result = execute(); - - span?.status = SpanStatus.ok(); + span.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; - return result; } catch (exception) { - span?.throwable = exception; - span?.status = SpanStatus.internalError(); - + span.throwable = exception; + span.status = SpanStatus.internalError(); breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; - rethrow; } finally { - span?.finish(); - - // ignore: invalid_use_of_internal_member + // Fire-and-forget for sync operations + span.finish(); _hub.scope.addBreadcrumb(breadcrumb); } } From 3cfb3fa72e20f52313b3a71114fa7aa92a61ed93 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:25:16 +0100 Subject: [PATCH 10/16] Update --- packages/file/lib/src/sentry_file.dart | 3 +-- packages/hive/lib/src/sentry_span_helper.dart | 5 +++-- packages/isar/lib/src/sentry_span_helper.dart | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/file/lib/src/sentry_file.dart b/packages/file/lib/src/sentry_file.dart index 1463d2e8a1..b989f43ff7 100644 --- a/packages/file/lib/src/sentry_file.dart +++ b/packages/file/lib/src/sentry_file.dart @@ -543,8 +543,7 @@ class SentryFile implements File { span?.status = SpanStatus.internalError(); rethrow; } finally { - // Fire-and-forget for sync operations - span?.finish(); + unawaited(span?.finish()); _hub.addBreadcrumb( Breadcrumb( diff --git a/packages/hive/lib/src/sentry_span_helper.dart b/packages/hive/lib/src/sentry_span_helper.dart index cdbfde3ccd..5fb83f76b8 100644 --- a/packages/hive/lib/src/sentry_span_helper.dart +++ b/packages/hive/lib/src/sentry_span_helper.dart @@ -1,5 +1,7 @@ // ignore_for_file: invalid_use_of_internal_member +import 'dart:async'; + import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; @@ -128,8 +130,7 @@ class SentrySpanHelper { breadcrumb.level = SentryLevel.warning; rethrow; } finally { - // Fire-and-forget for sync operations - span.finish(); + unawaited(span.finish()); _hub.scope.addBreadcrumb(breadcrumb); } } diff --git a/packages/isar/lib/src/sentry_span_helper.dart b/packages/isar/lib/src/sentry_span_helper.dart index 59c4752218..88be9a2a66 100644 --- a/packages/isar/lib/src/sentry_span_helper.dart +++ b/packages/isar/lib/src/sentry_span_helper.dart @@ -1,5 +1,7 @@ // ignore_for_file: invalid_use_of_internal_member +import 'dart:async'; + import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; @@ -136,8 +138,7 @@ class SentrySpanHelper { breadcrumb.level = SentryLevel.warning; rethrow; } finally { - // Fire-and-forget for sync operations - span.finish(); + unawaited(span.finish()); _hub.scope.addBreadcrumb(breadcrumb); } } From b7a26b540cfbb7f863eaf818de5cc87e6f0d8357 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:39:26 +0100 Subject: [PATCH 11/16] Update --- packages/link/lib/src/sentry_tracing_link.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/link/lib/src/sentry_tracing_link.dart b/packages/link/lib/src/sentry_tracing_link.dart index 724c77f8f0..46adb49570 100644 --- a/packages/link/lib/src/sentry_tracing_link.dart +++ b/packages/link/lib/src/sentry_tracing_link.dart @@ -89,7 +89,8 @@ class SentryTracingLink extends Link { if (parentSpan == null && shouldStartTransaction) { // Start a new transaction - InstrumentationSpan doesn't support this // so we use the legacy API and wrap it - final transaction = _hub.startTransaction(description, op, bindToScope: true); + final transaction = + _hub.startTransaction(description, op, bindToScope: true); return LegacyInstrumentationSpan(transaction); } else if (parentSpan != null) { return _spanFactory.createSpan(parentSpan, op, description: description); From abff1b6f500cd43f6ab82e5a77738f0057c69085 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:40:25 +0100 Subject: [PATCH 12/16] Update --- packages/drift/lib/src/internal_logger.dart | 1 - packages/hive/lib/src/internal_logger.dart | 1 - packages/isar/lib/src/internal_logger.dart | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/drift/lib/src/internal_logger.dart b/packages/drift/lib/src/internal_logger.dart index 9477c63d4e..29bd38f4fe 100644 --- a/packages/drift/lib/src/internal_logger.dart +++ b/packages/drift/lib/src/internal_logger.dart @@ -1,6 +1,5 @@ import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; -/// Internal logger for sentry_drift package. @internal const internalLogger = SentryInternalLogger('sentry_drift'); diff --git a/packages/hive/lib/src/internal_logger.dart b/packages/hive/lib/src/internal_logger.dart index 0e3546ce8a..bf048c87c8 100644 --- a/packages/hive/lib/src/internal_logger.dart +++ b/packages/hive/lib/src/internal_logger.dart @@ -1,6 +1,5 @@ import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; -/// Internal logger for sentry_hive package. @internal const internalLogger = SentryInternalLogger('sentry_hive'); diff --git a/packages/isar/lib/src/internal_logger.dart b/packages/isar/lib/src/internal_logger.dart index abb5ff37d6..83776ba137 100644 --- a/packages/isar/lib/src/internal_logger.dart +++ b/packages/isar/lib/src/internal_logger.dart @@ -1,6 +1,5 @@ import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; -/// Internal logger for sentry_isar package. @internal const internalLogger = SentryInternalLogger('sentry_isar'); From ab318174306a23023355022e34f909247d31f575 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 15:56:58 +0100 Subject: [PATCH 13/16] Update --- packages/hive/lib/src/sentry_span_helper.dart | 53 +++++------------ packages/isar/lib/src/sentry_span_helper.dart | 57 ++++++------------- 2 files changed, 32 insertions(+), 78 deletions(-) diff --git a/packages/hive/lib/src/sentry_span_helper.dart b/packages/hive/lib/src/sentry_span_helper.dart index 5fb83f76b8..99b5f8994e 100644 --- a/packages/hive/lib/src/sentry_span_helper.dart +++ b/packages/hive/lib/src/sentry_span_helper.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; -import 'internal_logger.dart'; import 'sentry_hive_impl.dart'; /// @nodoc @@ -28,27 +27,16 @@ class SentrySpanHelper { String? dbName, }) async { final parentSpan = _factory.getSpan(_hub); - if (parentSpan == null) { - internalLogger.warning( - 'No active span found. Skipping tracing for Hive operation: $description', - ); - return execute(); - } - final span = _factory.createSpan( parentSpan, SentryHiveImpl.dbOp, description: description, ); - if (span == null) { - return execute(); - } - - span.origin = _origin; - span.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); + span?.origin = _origin; + span?.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); if (dbName != null) { - span.setData(SentryHiveImpl.dbNameKey, dbName); + span?.setData(SentryHiveImpl.dbNameKey, dbName); } final breadcrumb = Breadcrumb( @@ -62,17 +50,17 @@ class SentrySpanHelper { try { final result = await execute(); - span.status = SpanStatus.ok(); + span?.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; return result; } catch (exception) { - span.throwable = exception; - span.status = SpanStatus.internalError(); + span?.throwable = exception; + span?.status = SpanStatus.internalError(); breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; rethrow; } finally { - await span.finish(); + await span?.finish(); await _hub.scope.addBreadcrumb(breadcrumb); } } @@ -85,28 +73,17 @@ class SentrySpanHelper { String? dbName, }) { final parentSpan = _factory.getSpan(_hub); - if (parentSpan == null) { - internalLogger.warning( - 'No active span found. Skipping tracing for Hive operation: $description', - ); - return execute(); - } - final span = _factory.createSpan( parentSpan, SentryHiveImpl.dbOp, description: description, ); - if (span == null) { - return execute(); - } - - span.origin = _origin; - span.setData('sync', true); - span.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); + span?.origin = _origin; + span?.setData('sync', true); + span?.setData(SentryHiveImpl.dbSystemKey, SentryHiveImpl.dbSystem); if (dbName != null) { - span.setData(SentryHiveImpl.dbNameKey, dbName); + span?.setData(SentryHiveImpl.dbNameKey, dbName); } final breadcrumb = Breadcrumb( @@ -120,17 +97,17 @@ class SentrySpanHelper { try { final result = execute(); - span.status = SpanStatus.ok(); + span?.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; return result; } catch (exception) { - span.throwable = exception; - span.status = SpanStatus.internalError(); + span?.throwable = exception; + span?.status = SpanStatus.internalError(); breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; rethrow; } finally { - unawaited(span.finish()); + unawaited(span?.finish()); _hub.scope.addBreadcrumb(breadcrumb); } } diff --git a/packages/isar/lib/src/sentry_span_helper.dart b/packages/isar/lib/src/sentry_span_helper.dart index 88be9a2a66..d2f06fa1d3 100644 --- a/packages/isar/lib/src/sentry_span_helper.dart +++ b/packages/isar/lib/src/sentry_span_helper.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:meta/meta.dart'; import 'package:sentry/sentry.dart'; -import 'internal_logger.dart'; import 'sentry_isar.dart'; /// @nodoc @@ -29,30 +28,19 @@ class SentrySpanHelper { String? collectionName, }) async { final parentSpan = _factory.getSpan(_hub); - if (parentSpan == null) { - internalLogger.warning( - 'No active span found. Skipping tracing for Isar operation: $description', - ); - return execute(); - } - final span = _factory.createSpan( parentSpan, SentryIsar.dbOp, description: description, ); - if (span == null) { - return execute(); - } - - span.origin = _origin; - span.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); + span?.origin = _origin; + span?.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); if (dbName != null) { - span.setData(SentryIsar.dbNameKey, dbName); + span?.setData(SentryIsar.dbNameKey, dbName); } if (collectionName != null) { - span.setData(SentryIsar.dbCollectionKey, collectionName); + span?.setData(SentryIsar.dbCollectionKey, collectionName); } final breadcrumb = Breadcrumb( @@ -66,17 +54,17 @@ class SentrySpanHelper { try { final result = await execute(); - span.status = SpanStatus.ok(); + span?.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; return result; } catch (exception) { - span.throwable = exception; - span.status = SpanStatus.internalError(); + span?.throwable = exception; + span?.status = SpanStatus.internalError(); breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; rethrow; } finally { - await span.finish(); + await span?.finish(); await _hub.scope.addBreadcrumb(breadcrumb); } } @@ -90,31 +78,20 @@ class SentrySpanHelper { String? collectionName, }) { final parentSpan = _factory.getSpan(_hub); - if (parentSpan == null) { - internalLogger.warning( - 'No active span found. Skipping tracing for Isar operation: $description', - ); - return execute(); - } - final span = _factory.createSpan( parentSpan, SentryIsar.dbOp, description: description, ); - if (span == null) { - return execute(); - } - - span.origin = _origin; - span.setData('sync', true); - span.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); + span?.origin = _origin; + span?.setData('sync', true); + span?.setData(SentryIsar.dbSystemKey, SentryIsar.dbSystem); if (dbName != null) { - span.setData(SentryIsar.dbNameKey, dbName); + span?.setData(SentryIsar.dbNameKey, dbName); } if (collectionName != null) { - span.setData(SentryIsar.dbCollectionKey, collectionName); + span?.setData(SentryIsar.dbCollectionKey, collectionName); } final breadcrumb = Breadcrumb( @@ -128,17 +105,17 @@ class SentrySpanHelper { try { final result = execute(); - span.status = SpanStatus.ok(); + span?.status = SpanStatus.ok(); breadcrumb.data?['status'] = 'ok'; return result; } catch (exception) { - span.throwable = exception; - span.status = SpanStatus.internalError(); + span?.throwable = exception; + span?.status = SpanStatus.internalError(); breadcrumb.data?['status'] = 'internal_error'; breadcrumb.level = SentryLevel.warning; rethrow; } finally { - unawaited(span.finish()); + unawaited(span?.finish()); _hub.scope.addBreadcrumb(breadcrumb); } } From ee0ec708049e439ce5a3131bcb7e01ceedd8b824 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 16:43:41 +0100 Subject: [PATCH 14/16] Update --- packages/isar/lib/src/sentry_span_helper.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/isar/lib/src/sentry_span_helper.dart b/packages/isar/lib/src/sentry_span_helper.dart index d2f06fa1d3..f6d4998ad4 100644 --- a/packages/isar/lib/src/sentry_span_helper.dart +++ b/packages/isar/lib/src/sentry_span_helper.dart @@ -46,6 +46,7 @@ class SentrySpanHelper { final breadcrumb = Breadcrumb( message: description, data: { + SentryIsar.dbSystemKey: SentryIsar.dbSystem, if (dbName != null) SentryIsar.dbNameKey: dbName, if (collectionName != null) SentryIsar.dbCollectionKey: collectionName, }, @@ -97,6 +98,7 @@ class SentrySpanHelper { final breadcrumb = Breadcrumb( message: description, data: { + SentryIsar.dbSystemKey: SentryIsar.dbSystem, if (dbName != null) SentryIsar.dbNameKey: dbName, if (collectionName != null) SentryIsar.dbCollectionKey: collectionName, }, From c8bd1b80ba51a730f1ab2dae1cb69eb9f4d588d1 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 22:44:45 +0100 Subject: [PATCH 15/16] feat(supabase): add internal logger and update dependencies - Introduced an internal logger using Sentry for better tracing. - Added 'meta' package as a dependency in pubspec.yaml. - Updated Sentry tracing logic to utilize the new internal logger for warnings. --- packages/supabase/lib/src/internal_logger.dart | 5 +++++ .../supabase/lib/src/sentry_supabase_tracing_client.dart | 8 +++----- packages/supabase/pubspec.yaml | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 packages/supabase/lib/src/internal_logger.dart diff --git a/packages/supabase/lib/src/internal_logger.dart b/packages/supabase/lib/src/internal_logger.dart new file mode 100644 index 0000000000..dc60f19aa4 --- /dev/null +++ b/packages/supabase/lib/src/internal_logger.dart @@ -0,0 +1,5 @@ +import 'package:meta/meta.dart'; +import 'package:sentry/sentry.dart'; + +@internal +const internalLogger = SentryInternalLogger('sentry_supabase'); diff --git a/packages/supabase/lib/src/sentry_supabase_tracing_client.dart b/packages/supabase/lib/src/sentry_supabase_tracing_client.dart index f699d4366a..32f980f783 100644 --- a/packages/supabase/lib/src/sentry_supabase_tracing_client.dart +++ b/packages/supabase/lib/src/sentry_supabase_tracing_client.dart @@ -3,7 +3,7 @@ import 'package:http/http.dart'; import 'package:sentry/sentry.dart'; -import 'constants.dart'; +import 'internal_logger.dart'; import 'sentry_supabase_request.dart'; class SentrySupabaseTracingClient extends BaseClient { @@ -62,10 +62,8 @@ class SentrySupabaseTracingClient extends BaseClient { InstrumentationSpan? _createSpan(SentrySupabaseRequest supabaseRequest) { final parentSpan = _spanFactory.getSpan(_hub); if (parentSpan == null) { - _hub.options.log( - SentryLevel.warning, - 'Active Sentry transaction does not exist, could not start span for the Supabase operation: from(${supabaseRequest.table})', - logger: loggerName, + internalLogger.warning( + 'No active span found. Skipping tracing for Supabase operation: from(${supabaseRequest.table})', ); return null; } diff --git a/packages/supabase/pubspec.yaml b/packages/supabase/pubspec.yaml index 076a4ab71f..b27e927dd1 100644 --- a/packages/supabase/pubspec.yaml +++ b/packages/supabase/pubspec.yaml @@ -10,6 +10,7 @@ environment: dependencies: http: ^1.3.0 + meta: ^1.3.0 sentry: 9.11.0-beta.1 dev_dependencies: From 37faf8b116233c2f8beee6d39fa022c9d32b33fc Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 28 Jan 2026 23:03:02 +0100 Subject: [PATCH 16/16] Update --- packages/hive/lib/src/internal_logger.dart | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 packages/hive/lib/src/internal_logger.dart diff --git a/packages/hive/lib/src/internal_logger.dart b/packages/hive/lib/src/internal_logger.dart deleted file mode 100644 index bf048c87c8..0000000000 --- a/packages/hive/lib/src/internal_logger.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:meta/meta.dart'; -import 'package:sentry/sentry.dart'; - -@internal -const internalLogger = SentryInternalLogger('sentry_hive');