Skip to content

Commit

Permalink
Gracefully handle analytics failing to send
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandradeas committed Jan 30, 2025
1 parent e465db0 commit eb17819
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 14 deletions.
4 changes: 4 additions & 0 deletions packages/patrol_cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## Unreleased

- Gracefully handle when analytics fail to send (#2460)

## 3.5.0

- Add `PATROL_ANALYTICS_ENABLED` environment variable to disable analytics. (#2483)
Expand Down
40 changes: 26 additions & 14 deletions packages/patrol_cli/lib/src/analytics/analytics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:file/file.dart';
import 'package:http/http.dart' as http;
import 'package:patrol_cli/src/base/constants.dart' as constants;
import 'package:patrol_cli/src/base/extensions/platform.dart';
import 'package:patrol_cli/src/base/logger.dart';
import 'package:patrol_cli/src/base/process.dart';
import 'package:patrol_cli/src/runner/flutter_command.dart';
import 'package:platform/platform.dart';
Expand Down Expand Up @@ -41,12 +42,14 @@ class Analytics {
http.Client? httpClient,
required bool isCI,
required bool? envAnalyticsEnabled,
required Logger logger,
}) : _fs = fs,
_platform = platform,
_httpClient = httpClient ?? http.Client(),
_postUrl = _getAnalyticsUrl(measurementId, apiSecret),
_isCI = isCI,
_envAnalyticsEnabled = envAnalyticsEnabled;
_envAnalyticsEnabled = envAnalyticsEnabled,
_logger = logger;

final FileSystem _fs;
final Platform _platform;
Expand All @@ -57,6 +60,8 @@ class Analytics {
final bool _isCI;
final bool? _envAnalyticsEnabled;

final Logger _logger;

/// Sends an event to Google Analytics that command [name] run.
///
/// Returns true if the event was sent, false otherwise.
Expand All @@ -78,19 +83,26 @@ class Analytics {
return false;
}

await _httpClient.post(
Uri.parse(_postUrl),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: _generateRequestBody(
flutterVersion: flutterVersion,
clientId: uuid,
eventName: name,
additionalEventData: eventData,
),
);
return true;
try {
await _httpClient.post(
Uri.parse(_postUrl),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: _generateRequestBody(
flutterVersion: flutterVersion,
clientId: uuid,
eventName: name,
additionalEventData: eventData,
),
);
return true;
} on Exception catch (e) {
_logger
..info('Failed to post analytics')
..detail(e.toString());
return false;
}
}

bool get firstRun => _config == null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Future<int> patrolCommandRunner(List<String> args) async {
platform: platform,
isCI: isCI,
envAnalyticsEnabled: analyticsEnabled,
logger: logger,
),
processManager: processManager,
isCI: isCI,
Expand Down
44 changes: 44 additions & 0 deletions packages/patrol_cli/test/analytics/analytics_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ void main() {
httpClient: httpClient,
isCI: false,
envAnalyticsEnabled: null,
logger: MockLogger(),
);
});

Expand Down Expand Up @@ -91,6 +92,7 @@ void main() {
httpClient: httpClient,
isCI: false,
envAnalyticsEnabled: true,
logger: MockLogger(),
);
});

Expand Down Expand Up @@ -145,6 +147,7 @@ void main() {
httpClient: httpClient,
isCI: false,
envAnalyticsEnabled: false,
logger: MockLogger(),
);
});

Expand Down Expand Up @@ -172,6 +175,47 @@ void main() {
expect(sent, false);
});
});

test('does not throw when failing to send data', () async {
setUpFakes();

final fs = MemoryFileSystem.test();

final httpClient = MockHttpClient();
when(
() => httpClient.post(
any(),
body: any(named: 'body'),
headers: any(named: 'headers'),
),
).thenThrow(
http.ClientException(
'Failed host lookup',
Uri(scheme: 'https', host: 'google-analytics.com'),
),
);

final analytics = Analytics(
measurementId: 'measurementId',
apiSecret: 'apiSecret',
fs: fs,
platform: fakePlatform('/Users/john'),
httpClient: httpClient,
isCI: false,
envAnalyticsEnabled: false,
logger: MockLogger(),
);

// given
_createFakeFileSystem(fs, analyticsEnabled: true);

// when
final sent =
await analytics.sendCommand(FlutterVersion.test(), 'test command');

// then
expect(sent, false);
});
}

void _createFakeFileSystem(FileSystem fs, {required bool analyticsEnabled}) {
Expand Down

0 comments on commit eb17819

Please sign in to comment.