Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
163cce7
Merge branch 'main' into feature/unified-api
marandaneto Oct 14, 2020
b91c954
Merge branch 'main' into feature/unified-api
marandaneto Oct 14, 2020
5018978
feat : static SDK main entry withSentry.init(options),... (#108)
rxlabz Oct 14, 2020
d577e35
Feat : add a Hub class (#113)
rxlabz Oct 19, 2020
fabf56f
feat: sentry options (#116)
marandaneto Oct 20, 2020
2b36bec
ref: Hub passes the Scope (#114)
marandaneto Oct 20, 2020
af3ecc0
Refacto : initialize SentryClient with SentryOptions (#118)
rxlabz Oct 20, 2020
19f5592
ref: SentryId generates UUID (#119)
marandaneto Oct 21, 2020
b51b0da
ref: Event now is SentryEvent and added GPU (#121)
marandaneto Oct 22, 2020
3fa0b79
feat: before breadcrumb and scope ref (#122)
marandaneto Oct 22, 2020
2cc1d78
Ref: Hint is passed across Sentry static class, Hub and Client (#124)
marandaneto Oct 22, 2020
11b821b
Ref: Remove stackFrameFilter in favor of beforeSendCallback (#125)
marandaneto Oct 22, 2020
ee737a2
Ref: Sentry init with null and empty DSN and close method (#126)
marandaneto Oct 22, 2020
eab4ccf
Refacto : add a Transport class (#123)
rxlabz Oct 23, 2020
c301ec6
Ref: execute before send callback (#128)
marandaneto Oct 24, 2020
1794f04
feat: addBreadcrumb to the Sentry static API (#133)
marandaneto Oct 26, 2020
e7db5d1
Feat: add lastEventId to the Sentry static API (#134)
marandaneto Oct 26, 2020
dc962ae
Fix: Breadcrumb data should accept serializable types and not only St…
marandaneto Oct 26, 2020
b9cd68b
Fix: NoOp encode for Web (#138)
marandaneto Oct 26, 2020
7b81890
Fix: execute Integrations on Hub creation (#136)
marandaneto Oct 26, 2020
b1761f4
unified api fixes and add web example (#137)
rxlabz Oct 27, 2020
d249c97
Ref/prepare event & scope.applyToEvent (#140)
rxlabz Oct 27, 2020
dc258d9
Ref : rename files accordely to their content (#141)
rxlabz Oct 27, 2020
c6669c3
rename the `throwable` argument to `exception` (#142)
rxlabz Oct 27, 2020
a0bb939
lint : prefer relative imports and show error when a @required argume…
rxlabz Oct 27, 2020
a7ca364
fix: Unified API code review (#144)
marandaneto Oct 28, 2020
56ac62a
Ref : remove dsn from Transport public API (#145)
rxlabz Oct 28, 2020
209f18a
Fix the pubspecs SDK constraints (#146)
rxlabz Oct 28, 2020
108ac6c
fix : throws on invalid dsn (#148)
rxlabz Oct 28, 2020
a81da3e
add comment to change the DSN
marandaneto Oct 28, 2020
c1812b7
update the workflow to run both on vm and on browser (#150)
rxlabz Oct 28, 2020
f597604
Bump sentry sdk to 4.0.0-alpha.1 (#151)
marandaneto Oct 28, 2020
6d9caff
remove TODOs
marandaneto Oct 28, 2020
32debd7
fix the web example pubspec (#153)
rxlabz Oct 28, 2020
c80365f
Ref: remove platform specific clients to use SentryClient (#152)
rxlabz Oct 29, 2020
2ed0f92
fix conflict
marandaneto Oct 29, 2020
c3ab59f
rewrite changelog
marandaneto Oct 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
ref: Hub passes the Scope (#114)
  • Loading branch information
marandaneto authored Oct 20, 2020
commit 2b36bec62601f1f013bcd6900516fbca9da4e2a7
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- expect a sdkName based on the test platform #105
- Added Scope and Breadcrumb ring buffer #109
- Added Hub to SDK #113
- Ref: Hub passes the Scope to SentryClient
- feat: sentry options #116

# `package:sentry` changelog
Expand Down
8 changes: 5 additions & 3 deletions dart/lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,13 @@ abstract class SentryClient {
}

/// Reports the [throwable] and optionally its [stackTrace] to Sentry.io.
Future<SentryId> captureException(dynamic throwable, {dynamic stackTrace}) {
Future<SentryId> captureException(dynamic throwable,
{dynamic stackTrace, Scope scope}) {
final event = Event(
exception: throwable,
stackTrace: stackTrace,
);
return captureEvent(event);
return captureEvent(event, scope: scope);
}

/// Reports the [template]
Expand All @@ -211,12 +212,13 @@ abstract class SentryClient {
SentryLevel level = SentryLevel.info,
String template,
List<dynamic> params,
Scope scope,
}) {
final event = Event(
message: Message(formatted, template: template, params: params),
level: level,
);
return captureEvent(event);
return captureEvent(event, scope: scope);
}

Future<void> close() async {
Expand Down
38 changes: 18 additions & 20 deletions dart/lib/src/hub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ class Hub {
);
}

final ListQueue<_StackItem> _stack;
final ListQueue<_StackItem> _stack = ListQueue();

/// if stack is empty, it throws IterableElementError.noElement()
_StackItem _peek() => _stack.isNotEmpty ? _stack.first : null;

final SentryOptions _options;

Expand All @@ -32,20 +35,18 @@ class Hub {
return Hub._(options);
}

Hub._(SentryOptions options)
: _options = options,
_stack = ListQueue() {
Hub._(SentryOptions options) : _options = options {
_stack.add(_StackItem(_getClient(fromOptions: options), Scope(_options)));
_isEnabled = true;
}

static void _validateOptions(SentryOptions options) {
if (options == null) {
throw ArgumentError.notNull('options');
throw ArgumentError.notNull('SentryOptions is required.');
}

if (options.dsn == null) {
throw ArgumentError.notNull('options.dsn');
if (options.dsn?.isNotEmpty != true) {
throw ArgumentError.notNull('DSN is required.');
}
}

Expand All @@ -54,7 +55,7 @@ class Hub {
/// Check if the Hub is enabled/active.
bool get isEnabled => _isEnabled;

SentryId _lastEventId;
SentryId _lastEventId = SentryId.empty();

/// Last event id recorded in the current scope
SentryId get lastEventId => _lastEventId;
Expand All @@ -74,7 +75,7 @@ class Hub {
'captureEvent called with null parameter.',
);
} else {
final item = _stack.first;
final item = _peek();
if (item != null) {
try {
sentryId = await item.client.captureEvent(event, scope: item.scope);
Expand Down Expand Up @@ -115,14 +116,11 @@ class Hub {
'captureException called with null parameter.',
);
} else {
final item = _stack.first;
final item = _peek();
if (item != null) {
try {
// TODO pass the scope
sentryId = await item.client.captureException(
throwable,
stackTrace: stackTrace,
);
sentryId = await item.client.captureException(throwable,
stackTrace: stackTrace, scope: item.scope);
} catch (err) {
_options.logger(
SentryLevel.error,
Expand Down Expand Up @@ -162,15 +160,15 @@ class Hub {
'captureMessage called with null parameter.',
);
} else {
final item = _stack.first;
final item = _peek();
if (item != null) {
try {
// TODO pass the scope
sentryId = await item.client.captureMessage(
message,
level: level,
template: template,
params: params,
scope: item.scope,
);
} catch (err) {
_options.logger(
Expand All @@ -196,7 +194,7 @@ class Hub {
_options.logger(SentryLevel.warning,
"Instance is disabled and this 'bindClient' call is a no-op.");
} else {
final item = _stack.first;
final item = _peek();
if (item != null) {
if (client != null) {
_options.logger(SentryLevel.debug, 'New client bound to scope.');
Expand Down Expand Up @@ -234,7 +232,7 @@ class Hub {
"Instance is disabled and this 'close' call is a no-op.",
);
} else {
final item = _stack.first;
final item = _peek();
if (item != null) {
try {
item.client.close();
Expand Down Expand Up @@ -262,7 +260,7 @@ class Hub {
"Instance is disabled and this 'configureScope' call is a no-op.",
);
} else {
final item = _stack.first;
final item = _peek();
if (item != null) {
try {
callback(item.scope);
Expand Down
12 changes: 11 additions & 1 deletion dart/lib/src/noop_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ import 'package:http/src/client.dart';

import 'client.dart';
import 'protocol.dart';
import 'scope.dart';

class NoOpSentryClient implements SentryClient {
NoOpSentryClient._();

static final NoOpSentryClient _instance = NoOpSentryClient._();

factory NoOpSentryClient() {
return _instance;
}

@override
User userContext;

Expand All @@ -24,7 +33,7 @@ class NoOpSentryClient implements SentryClient {
Future.value(SentryId.empty());

@override
Future<SentryId> captureException(throwable, {stackTrace}) =>
Future<SentryId> captureException(throwable, {stackTrace, scope}) =>
Future.value(SentryId.empty());

@override
Expand All @@ -33,6 +42,7 @@ class NoOpSentryClient implements SentryClient {
SentryLevel level = SentryLevel.info,
String template,
List<dynamic> params,
Scope scope,
}) =>
Future.value(SentryId.empty());

Expand Down
6 changes: 3 additions & 3 deletions dart/lib/src/protocol/sentry_id.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
/// Sentry response id

class SentryId {
static const String emptyId = '00000000-0000-0000-0000-000000000000';
static const String _emptyId = '00000000-0000-0000-0000-000000000000';

/// The ID Sentry.io assigned to the submitted event for future reference.
final String _id;

String get id => _id;
// TODO: should we generate the new UUID here with an empty ctor?

const SentryId(this._id);

factory SentryId.empty() => SentryId(emptyId);
factory SentryId.empty() => SentryId(_emptyId);

@override
String toString() => _id.replaceAll('-', '');
Expand Down
47 changes: 42 additions & 5 deletions dart/lib/src/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,76 @@ import 'client.dart';
import 'hub.dart';
import 'protocol.dart';
import 'sentry_options.dart';
import 'noop_hub.dart';

/// Configuration options callback
typedef OptionsConfiguration = void Function(SentryOptions);

/// Sentry SDK main entry point
///
class Sentry {
static Hub _hub;
static Hub _hub = NoOpHub();

Sentry._();

/// Returns the current hub
static Hub get currentHub => _hub;

/// Initializes the SDK
static void init(OptionsConfiguration optionsConfiguration) {
final options = SentryOptions();
optionsConfiguration(options);
_init(options);
}

/// Initializes the SDK
static void _init(SentryOptions options) {
if (isEnabled) {
options.logger(
SentryLevel.warning,
'Sentry has been already initialized. Previous configuration will be overwritten.',
);
}

_setDefaultConfiguration(options);

final hub = currentHub;
_hub = Hub(options);
hub.close();
}

/// Reports an [event] to Sentry.io.
static Future<SentryId> captureEvent(Event event) async {
return _hub.captureEvent(event);
return currentHub.captureEvent(event);
}

/// Reports the [exception] and optionally its [stackTrace] to Sentry.io.
static Future<SentryId> captureException(
dynamic error, {
dynamic stackTrace,
}) async {
return _hub.captureException(error, stackTrace: stackTrace);
return currentHub.captureException(error, stackTrace: stackTrace);
}

Future<SentryId> captureMessage(
String message, {
SentryLevel level,
String template,
List<dynamic> params,
}) async {
return currentHub.captureMessage(
message,
level: level,
template: template,
params: params,
);
}

/// Close the client SDK
static Future<void> close() async => _hub.close();
static Future<void> close() async => currentHub.close();

/// Check if the current Hub is enabled/active.
static bool get isEnabled => currentHub.isEnabled;

static void _setDefaultConfiguration(SentryOptions options) {
// TODO: check DSN nullability and empty
Expand All @@ -50,5 +87,5 @@ class Sentry {

/// client injector only use for testing
@visibleForTesting
static void initClient(SentryClient client) => _hub.bindClient(client);
static void initClient(SentryClient client) => currentHub.bindClient(client);
}
9 changes: 7 additions & 2 deletions dart/test/hub_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,18 @@ void main() {
test('should capture exception', () {
hub.captureException(fakeException);

verify(client.captureException(fakeException)).called(1);
verify(client.captureException(fakeException, scope: anyNamed('scope')))
.called(1);
});

test('should capture message', () {
hub.captureMessage(fakeMessage.formatted, level: SentryLevel.info);
verify(
client.captureMessage(fakeMessage.formatted, level: SentryLevel.info),
client.captureMessage(
fakeMessage.formatted,
level: SentryLevel.info,
scope: anyNamed('scope'),
),
).called(1);
});
});
Expand Down
6 changes: 5 additions & 1 deletion dart/test/sentry_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ void main() {
test('should capture the exception', () async {
await Sentry.captureException(anException);
verify(
client.captureException(anException, stackTrace: null),
client.captureException(
anException,
stackTrace: null,
scope: anyNamed('scope'),
),
).called(1);
});
});
Expand Down
1 change: 1 addition & 0 deletions dart/test/stack_trace_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ void main() {
});

test('allows changing the stack frame list before sending', () {
// ignore: omit_local_variable_types
final StackFrameFilter filter =
(list) => list.where((f) => f['abs_path'] != 'secret.dart').toList();

Expand Down
13 changes: 6 additions & 7 deletions dart/test/test_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Future testCaptureException(
} catch (error, stackTrace) {
final sentryId =
await client.captureException(error, stackTrace: stackTrace);
expect('${sentryId.id}', 'test-event-id');
expect('$sentryId', 'testeventid');
}

expect(postUri, client.postUri);
Expand All @@ -106,13 +106,12 @@ Future testCaptureException(
} else {
data = json.decode(utf8.decode(body)) as Map<String, dynamic>;
}
final Map<String, dynamic> stacktrace =
data.remove('stacktrace') as Map<String, dynamic>;
final stacktrace = data.remove('stacktrace') as Map<String, dynamic>;

expect(stacktrace['frames'], const TypeMatcher<List>());
expect(stacktrace['frames'], isNotEmpty);

final Map<String, dynamic> topFrame =
final topFrame =
(stacktrace['frames'] as Iterable<dynamic>).last as Map<String, dynamic>;
expect(topFrame.keys, <String>[
'abs_path',
Expand Down Expand Up @@ -222,7 +221,7 @@ void runTest({Codec<List<int>, List<int>> gzip, bool isWeb = false}) {
final httpMock = MockClient((Request request) async {
if (request.method == 'POST') {
headers = request.headers;
return Response('{"id": "test-event-id"}', 200);
return Response('{"id": "testeventid"}', 200);
}
fail(
'Unexpected request on ${request.method} ${request.url} in HttpMock');
Expand All @@ -246,7 +245,7 @@ void runTest({Codec<List<int>, List<int>> gzip, bool isWeb = false}) {
} catch (error, stackTrace) {
final sentryId =
await client.captureException(error, stackTrace: stackTrace);
expect('${sentryId.id}', 'test-event-id');
expect('$sentryId', 'testeventid');
}

testHeaders(
Expand Down Expand Up @@ -302,7 +301,7 @@ void runTest({Codec<List<int>, List<int>> gzip, bool isWeb = false}) {
} catch (error, stackTrace) {
final sentryId =
await client.captureException(error, stackTrace: stackTrace);
expect('${sentryId.id}', SentryId.emptyId);
expect('$sentryId', '00000000000000000000000000000000');
}

await client.close();
Expand Down