diff --git a/CHANGELOG.md b/CHANGELOG.md index be0b28da64..2131367c44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Features +- Add dart platform to sentry frames ([#2193](https://github.com/getsentry/sentry-dart/pull/2193)) + - This allows viewing the correct dart formatted raw stacktrace in the Sentry UI - Support `ignoredExceptionsForType` ([#2150](https://github.com/getsentry/sentry-dart/pull/2150)) - Filter out exception types by calling `SentryOptions.addExceptionFilterForType(Type exceptionType)` diff --git a/dart/lib/src/sentry_stack_trace_factory.dart b/dart/lib/src/sentry_stack_trace_factory.dart index 25a97e6eab..7aab228a3e 100644 --- a/dart/lib/src/sentry_stack_trace_factory.dart +++ b/dart/lib/src/sentry_stack_trace_factory.dart @@ -103,6 +103,7 @@ class SentryStackTraceFactory { // least we get an indication something's wrong and are able to fix it. } + final platform = _options.platformChecker.isWeb ? 'javascript' : 'dart'; final fileName = frame.uri.pathSegments.isNotEmpty ? frame.uri.pathSegments.last : null; final abs = '$eventOrigin${_absolutePathForCrashReport(frame)}'; @@ -114,6 +115,7 @@ class SentryStackTraceFactory { inApp: _isInApp(frame), fileName: fileName, package: frame.package, + platform: platform, ); final line = frame.line; diff --git a/dart/test/stack_trace_test.dart b/dart/test/stack_trace_test.dart index 3ab8f9d116..3636d845a4 100644 --- a/dart/test/stack_trace_test.dart +++ b/dart/test/stack_trace_test.dart @@ -9,6 +9,7 @@ import 'package:stack_trace/stack_trace.dart'; import 'package:test/test.dart'; import 'mocks.dart'; +import 'mocks/mock_platform_checker.dart'; void main() { group('encodeStackTraceFrame', () { @@ -23,7 +24,8 @@ void main() { 'lineno': 1, 'colno': 2, 'in_app': false, - 'filename': 'core' + 'filename': 'core', + 'platform': 'dart', }, ); }); @@ -123,7 +125,8 @@ void main() { 'lineno': 46, 'colno': 9, 'in_app': true, - 'filename': 'test.dart' + 'filename': 'test.dart', + 'platform': 'dart', }, { 'abs_path': '${eventOrigin}test.dart', @@ -131,7 +134,8 @@ void main() { 'lineno': 50, 'colno': 3, 'in_app': true, - 'filename': 'test.dart' + 'filename': 'test.dart', + 'platform': 'dart', }, ]); }); @@ -152,7 +156,8 @@ void main() { 'lineno': 46, 'colno': 9, 'in_app': true, - 'filename': 'test.dart' + 'filename': 'test.dart', + 'platform': 'dart', }, { 'abs_path': '', @@ -163,7 +168,8 @@ void main() { 'lineno': 50, 'colno': 3, 'in_app': true, - 'filename': 'test.dart' + 'filename': 'test.dart', + 'platform': 'dart', }, ]); }); @@ -229,7 +235,8 @@ isolate_instructions: 10fa27070, vm_instructions: 10fa21e20 'function': 'PlatformDispatcher._dispatchPointerDataPacket', 'lineno': 341, 'abs_path': '${eventOrigin}dart:ui/platform_dispatcher.dart', - 'in_app': false + 'in_app': false, + 'platform': 'dart', }, { 'filename': 'main.dart', @@ -237,14 +244,16 @@ isolate_instructions: 10fa27070, vm_instructions: 10fa21e20 'function': 'MainScaffold.build.', 'lineno': 131, 'abs_path': '${eventOrigin}package:example/main.dart', - 'in_app': true + 'in_app': true, + 'platform': 'dart', }, { 'filename': 'main.dart', 'function': 'asyncThrows', 'lineno': 404, 'abs_path': '${eventOrigin}main.dart', - 'in_app': true + 'in_app': true, + 'platform': 'dart', } ]); }); @@ -258,6 +267,29 @@ isolate_instructions: 10fa27070, vm_instructions: 10fa21e20 .map((frame) => frame.toJson()); expect(frames.isEmpty, true); }); + + test('sets platform to javascript for web and dart for non-web', () { + final frame = Frame(Uri.parse('file://foo/bar/baz.dart'), 1, 2, 'buzz'); + final fixture = Fixture(); + + // Test for web platform + final webSut = fixture.getSut(isWeb: true); + var webFrame = webSut.encodeStackTraceFrame(frame)!; + expect(webFrame.platform, 'javascript'); + + // Test for non-web platform + final nativeFrameBeforeSut = fixture.getSut(isWeb: false); + var nativeFrameBefore = + nativeFrameBeforeSut.encodeStackTraceFrame(frame)!; + expect(nativeFrameBefore.platform, 'dart'); + + // Test when platform is already set + final frameWithPlatform = fixture + .getSut() + .encodeStackTraceFrame(frame)! + .copyWith(platform: 'native'); + expect(frameWithPlatform.platform, 'native'); + }); }); } @@ -266,8 +298,10 @@ class Fixture { List inAppIncludes = const [], List inAppExcludes = const [], bool considerInAppFramesByDefault = true, + bool isWeb = false, }) { - final options = SentryOptions(dsn: fakeDsn); + final options = SentryOptions( + dsn: fakeDsn, checker: MockPlatformChecker(isWebValue: isWeb)); inAppIncludes.forEach(options.addInAppInclude); inAppExcludes.forEach(options.addInAppExclude); options.considerInAppFramesByDefault = considerInAppFramesByDefault; diff --git a/dart/test/test_utils.dart b/dart/test/test_utils.dart index 87a0be0f0a..c7a0138a76 100644 --- a/dart/test/test_utils.dart +++ b/dart/test/test_utils.dart @@ -124,7 +124,15 @@ Future testCaptureException( } expect( topFrame.keys, - ['filename', 'function', 'lineno', 'colno', 'abs_path', 'in_app'], + [ + 'filename', + 'function', + 'lineno', + 'colno', + 'abs_path', + 'in_app', + 'platform' + ], ); if (isWeb) {