diff --git a/packages/patrol_cli/CHANGELOG.md b/packages/patrol_cli/CHANGELOG.md index 65fafc75a..1edc24b97 100644 --- a/packages/patrol_cli/CHANGELOG.md +++ b/packages/patrol_cli/CHANGELOG.md @@ -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) diff --git a/packages/patrol_cli/lib/src/analytics/analytics.dart b/packages/patrol_cli/lib/src/analytics/analytics.dart index 9db20f35c..a3001d8ea 100644 --- a/packages/patrol_cli/lib/src/analytics/analytics.dart +++ b/packages/patrol_cli/lib/src/analytics/analytics.dart @@ -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'; @@ -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; @@ -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. @@ -78,19 +83,26 @@ class Analytics { return false; } - await _httpClient.post( - Uri.parse(_postUrl), - headers: { - '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: { + '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; diff --git a/packages/patrol_cli/lib/src/runner/patrol_command_runner.dart b/packages/patrol_cli/lib/src/runner/patrol_command_runner.dart index 0c1ef4d5d..d691949ff 100644 --- a/packages/patrol_cli/lib/src/runner/patrol_command_runner.dart +++ b/packages/patrol_cli/lib/src/runner/patrol_command_runner.dart @@ -57,6 +57,7 @@ Future patrolCommandRunner(List args) async { platform: platform, isCI: isCI, envAnalyticsEnabled: analyticsEnabled, + logger: logger, ), processManager: processManager, isCI: isCI, diff --git a/packages/patrol_cli/test/analytics/analytics_test.dart b/packages/patrol_cli/test/analytics/analytics_test.dart index 66e04978d..b35d7c021 100644 --- a/packages/patrol_cli/test/analytics/analytics_test.dart +++ b/packages/patrol_cli/test/analytics/analytics_test.dart @@ -37,6 +37,7 @@ void main() { httpClient: httpClient, isCI: false, envAnalyticsEnabled: null, + logger: MockLogger(), ); }); @@ -91,6 +92,7 @@ void main() { httpClient: httpClient, isCI: false, envAnalyticsEnabled: true, + logger: MockLogger(), ); }); @@ -145,6 +147,7 @@ void main() { httpClient: httpClient, isCI: false, envAnalyticsEnabled: false, + logger: MockLogger(), ); }); @@ -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}) {