Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6a5d2c3
hub interface & instanciation
rxlabz Oct 15, 2020
4f01775
- hub capture event
rxlabz Oct 15, 2020
ea5c55f
- hub capture exception
rxlabz Oct 15, 2020
bd09da0
hub captureMessage
rxlabz Oct 15, 2020
c5317a4
fix some tests
rxlabz Oct 15, 2020
6a8910e
fix more tests
rxlabz Oct 15, 2020
f5d3dd0
changelog
rxlabz Oct 15, 2020
f102ac3
fix all tests
rxlabz Oct 15, 2020
055b9b0
feedbacks
rxlabz Oct 15, 2020
370d2d5
fix test : revert to ArgumentError.notNull('options')
rxlabz Oct 15, 2020
974d1f6
remove required hub methods
rxlabz Oct 15, 2020
c8c1df0
implement `Hub.close()`
rxlabz Oct 16, 2020
6c6c649
feedbacks : remove the IHub interface + minors
rxlabz Oct 16, 2020
a924040
Hub.configureScope
rxlabz Oct 16, 2020
823c91c
Hub.clone and Scope.clone
rxlabz Oct 16, 2020
b04d67c
remove the non required scope methods
rxlabz Oct 16, 2020
37cf83c
replace the ListQueue _stack by a DoubleLinkedQueue
rxlabz Oct 16, 2020
b9f9f9e
rename `response` to `sentryId`
rxlabz Oct 16, 2020
5067a36
serialize the potential error stackTrace
rxlabz Oct 16, 2020
54729ba
Revert the DoubleLinkedQueue to a resourceless ListQueue
rxlabz Oct 16, 2020
729d6bc
fix a json serialization test
rxlabz Oct 16, 2020
4ea1537
add a const SentryId.emptyId
rxlabz Oct 16, 2020
5932534
don't assign a new lastEventId if the client capture method is not ca…
rxlabz Oct 16, 2020
97f6c53
feedbacks:
rxlabz Oct 16, 2020
e89c488
feedbacks:
rxlabz Oct 16, 2020
647f1b0
simplify the captureMessage API
rxlabz Oct 19, 2020
91f709a
capture message
rxlabz Oct 19, 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
- hub capture event
- replace SentryResponse with SentryId
  • Loading branch information
rxlabz committed Oct 15, 2020
commit 4f017756f4c8694e8cfa4d3a7d47cb5cdce8f32b
11 changes: 4 additions & 7 deletions dart/example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ Future<void> main(List<String> rawArgs) async {
// Sends a full Sentry event payload to show the different parts of the UI.
final response = await Sentry.captureEvent(event);

if (response.isSuccessful) {
print('SentryId : ${response.id}');
/*if (response.isSuccessful) {
print('SUCCESS\nid: ${response.eventId}');
} else {
print('FAILURE: ${response.error}');
}
}*/

try {
await foo();
Expand All @@ -41,11 +42,7 @@ Future<void> main(List<String> rawArgs) async {
stackTrace: stackTrace,
);

if (response.isSuccessful) {
print('SUCCESS\nid: ${response.eventId}');
} else {
print('FAILURE: ${response.error}');
}
print('SentryId : ${response.id}');
} finally {
await Sentry.close();
}
Expand Down
8 changes: 4 additions & 4 deletions dart/lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ abstract class SentryClient {
}

/// Reports an [event] to Sentry.io.
Future<SentryResponse> captureEvent({
Future<SentryId> captureEvent({
@required Event event,
StackFrameFilter stackFrameFilter,
}) async {
Expand Down Expand Up @@ -187,15 +187,15 @@ abstract class SentryClient {
if (response.headers['x-sentry-error'] != null) {
errorMessage += ': ${response.headers['x-sentry-error']}';
}
return SentryResponse.failure(errorMessage);
return SentryId.empty();
}

final eventId = '${json.decode(response.body)['id']}';
return SentryResponse.success(eventId: eventId);
return SentryId(eventId);
}

/// Reports the [exception] and optionally its [stackTrace] to Sentry.io.
Future<SentryResponse> captureException({
Future<SentryId> captureException({
@required dynamic exception,
dynamic stackTrace,
}) {
Expand Down
67 changes: 49 additions & 18 deletions dart/lib/src/hub.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import 'dart:async';
import 'dart:collection';

import 'package:meta/meta.dart';

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

typedef ScopeCallback = void Function(Scope);

/// SDK API contract which combines a client and scope management
class Hub implements HubInterface {
static SentryClient _getClient({SentryOptions fromOptions}) => SentryClient(
Expand All @@ -20,16 +21,18 @@ class Hub implements HubInterface {

final ListQueue<_StackItem> _stack;

final SentryOptions _options;

factory Hub(SentryOptions options) {
_validateOptions(options);

final client = _getClient(fromOptions: options);
return Hub._(client: client, scope: Scope(options));
return Hub._(options);
}

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

Expand All @@ -54,9 +57,40 @@ class Hub implements HubInterface {
SentryId get lastEventId => _lastEventId;

@override
SentryId captureEvent(Event event) {
// TODO: implement captureEvent
throw UnimplementedError();
Future<SentryId> captureEvent(Event event) async {
var sentryId = SentryId.empty();

if (!_isEnabled) {
_options.logger(
SeverityLevel.warning,
"Instance is disabled and this 'captureEvent' call is a no-op.",
);
} else if (event == null) {
_options.logger(
SeverityLevel.warning,
'captureEvent called with null parameter.',
);
} else {
final item = _stack.last;
if (item != null) {
try {
sentryId = await item.client.captureEvent(event: event);
} catch (err) {
/* FIXME(rxlabz) ? Event.id ?*/
_options.logger(
SeverityLevel.error,
'Error while capturing event with id: ${event}',
);
}
} else {
_options.logger(
SeverityLevel.fatal,
'Stack peek was null when captureEvent',
);
}
}
_lastEventId = sentryId;
return sentryId;
}

@override
Expand All @@ -79,8 +113,7 @@ class Hub implements HubInterface {

@override
void bindClient(SentryClient client) {
// TODO: implement bindClient
throw UnimplementedError();
_stack.add(_StackItem(client, _stack.last.scope));
}

@override
Expand Down Expand Up @@ -187,11 +220,11 @@ class Hub implements HubInterface {
}

class _StackItem {
final SentryClient _client;
final SentryClient client;

final Scope _scope;
final Scope scope;

_StackItem(this._client, this._scope);
_StackItem(this.client, this.scope);
}

abstract class HubInterface {
Expand All @@ -202,7 +235,7 @@ abstract class HubInterface {
SentryId get lastEventId;

/// Captures the event.
SentryId captureEvent(Event event);
Future<SentryId> captureEvent(Event event);

/// Captures the exception
SentryId captureException({Message message, SeverityLevel level});
Expand Down Expand Up @@ -270,5 +303,3 @@ abstract class HubInterface {
/// Clones the Hub
Hub clone();
}

typedef ScopeCallback = void Function(Scope);
9 changes: 9 additions & 0 deletions dart/lib/src/protocol/sentry_id.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
/// Sentry response id

const _dashIndexed = [8, 13, 18, 23];

class SentryId {
static final String emptyId =
List.generate(36, (index) => _dashIndexed.contains(index) ? '-' : '0')
.join();

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

const SentryId(this.id);

factory SentryId.empty() => SentryId(emptyId);
}
24 changes: 13 additions & 11 deletions dart/lib/src/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:async';
import 'package:meta/meta.dart';

import 'client.dart';
import 'hub.dart';
import 'protocol.dart';
import 'sentry_options.dart';

Expand All @@ -12,43 +13,44 @@ typedef OptionsConfiguration = void Function(SentryOptions);
/// Sentry SDK main entry point
///
class Sentry {
static SentryClient _client;
static Hub _hub;

Sentry._();

static void init(OptionsConfiguration optionsConfiguration) {
final options = SentryOptions();
optionsConfiguration(options);
_client = SentryClient(
_hub = Hub(options);
/*_client = SentryClient(
dsn: options.dsn,
environmentAttributes: options.environmentAttributes,
compressPayload: options.compressPayload,
httpClient: options.httpClient,
clock: options.clock,
uuidGenerator: options.uuidGenerator,
);
);*/
}

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

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

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

/// client injector only use for testing
@visibleForTesting
static void initClient(SentryClient client) => _client = client;
static void initClient(SentryClient client) => _hub.bindClient(client);
}
14 changes: 13 additions & 1 deletion dart/lib/src/sentry_options.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import 'package:http/http.dart';
import 'package:sentry/sentry.dart';

import 'protocol.dart';
import 'utils.dart';

typedef Logger = void Function(SeverityLevel, String);

/// Sentry SDK options
class SentryOptions {
/// Default Log level if not specified Default is DEBUG
Expand Down Expand Up @@ -44,13 +47,22 @@ class SentryOptions {

int maxBreadcrumbs;

final Logger _logger;

Logger get logger => _logger ?? defaultLogger;

SentryOptions({
this.dsn,
this.environmentAttributes,
this.compressPayload,
this.httpClient,
this.clock,
this.uuidGenerator,
Logger logger,
this.maxBreadcrumbs = 100,
});
}) : _logger = logger;
}

void defaultLogger({SeverityLevel level, String message}) {
print('[$level] $message');
}
4 changes: 3 additions & 1 deletion dart/test/hub_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import 'mocks.dart';
void main() {
group('Hub instanciation', () {
test('should not instanciate without a sentryOptions', () {
expect(() => Hub(null), throwsArgumentError);
Hub hub;
expect(() => hub = Hub(null), throwsArgumentError);
expect(hub, null);
});

test('should not instanciate without a dsn', () {
Expand Down
5 changes: 0 additions & 5 deletions dart/test/sentry_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ void main() {
verify(client.captureEvent(event: event)).called(1);
});

test('should capture the event', () {
Sentry.captureEvent(event);
verify(client.captureEvent(event: event)).called(1);
});

test('should capture the exception', () {
Sentry.captureException(anException);
verify(client.captureException(exception: anException)).called(1);
Expand Down
19 changes: 9 additions & 10 deletions dart/test/test_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,8 @@ Future testCaptureException(
} catch (error, stackTrace) {
final response =
await client.captureException(exception: error, stackTrace: stackTrace);
expect(response.isSuccessful, true);
expect(response.eventId, 'test-event-id');
expect(response.error, null);
//expect(response.isSuccessful, true);
expect(response.id, 'test-event-id');
}

expect(postUri, client.postUri);
Expand Down Expand Up @@ -247,9 +246,9 @@ void runTest({Codec<List<int>, List<int>> gzip, bool isWeb = false}) {
} catch (error, stackTrace) {
final response = await client.captureException(
exception: error, stackTrace: stackTrace);
expect(response.isSuccessful, true);
expect(response.eventId, 'test-event-id');
expect(response.error, null);
//expect(response.isSuccessful, true);
expect(response.id, 'test-event-id');
//expect(response.error, null);
}

testHeaders(
Expand Down Expand Up @@ -305,10 +304,10 @@ void runTest({Codec<List<int>, List<int>> gzip, bool isWeb = false}) {
} catch (error, stackTrace) {
final response = await client.captureException(
exception: error, stackTrace: stackTrace);
expect(response.isSuccessful, false);
expect(response.eventId, null);
expect(
response.error, 'Sentry.io responded with HTTP 401: Invalid api key');
//expect(response.isSuccessful, false);
expect(response.id, SentryId.emptyId);
/*expect(
response.error, 'Sentry.io responded with HTTP 401: Invalid api key');*/
}

await client.close();
Expand Down