fix: add git hash to crash screen and extend DB path retries (#179)
Two issues from #179: - crash_screen.dart now reads GIT_HASH compile-time constant and includes 'Git Commit: <hash>' in both the on-screen UI and the copied report, so crash reports always show the exact build that crashed. - _resolveDatabasePath() retry delays extended from [100, 300, 600] ms (total ~1 s, 4 attempts) to [200, 500, 1000, 2000, 4000] ms (total ~7.7 s, 6 attempts) to handle slow/non-standard Android devices where the path_provider Pigeon channel takes several seconds to become ready. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
dcb0cbd539
commit
37abd5abb6
@@ -596,8 +596,10 @@ Future<void> initDatabasePath() async {
|
||||
Future<String> _resolveDatabasePath() async {
|
||||
if (_dbPath != null) return _dbPath!;
|
||||
// initDatabasePath() failed (channel not ready before runApp). Retry now
|
||||
// that the engine is fully initialised, with brief back-off.
|
||||
const delays = [100, 300, 600];
|
||||
// that the engine is fully initialised, with exponential back-off.
|
||||
// Longer delays handle slow/non-standard Android devices where the Pigeon
|
||||
// channel takes several seconds to become available.
|
||||
const delays = [200, 500, 1000, 2000, 4000];
|
||||
for (final ms in delays) {
|
||||
try {
|
||||
final dir = await getApplicationSupportDirectory();
|
||||
|
||||
@@ -15,15 +15,19 @@ class CrashScreen extends StatelessWidget {
|
||||
final Object exception;
|
||||
final StackTrace? stackTrace;
|
||||
|
||||
static const _gitHash = String.fromEnvironment('GIT_HASH');
|
||||
|
||||
Future<String> _buildReport() async {
|
||||
String version = 'unknown';
|
||||
try {
|
||||
final info = await PackageInfo.fromPlatform();
|
||||
version = '${info.version}+${info.buildNumber}';
|
||||
} catch (_) {}
|
||||
final gitLine = _gitHash.isNotEmpty ? 'Git Commit: $_gitHash\n' : '';
|
||||
final platform =
|
||||
'${Platform.operatingSystem} ${Platform.operatingSystemVersion}';
|
||||
return 'App Version: $version\n'
|
||||
'$gitLine'
|
||||
'Platform: $platform\n\n'
|
||||
'Error:\n```\n$exception\n```\n\n'
|
||||
'Stack Trace:\n```\n$stackTrace\n```';
|
||||
@@ -50,6 +54,14 @@ class CrashScreen extends StatelessWidget {
|
||||
style: Theme.of(ctx).textTheme.titleMedium,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
if (_gitHash.isNotEmpty) ...[
|
||||
const SizedBox(height: 8),
|
||||
const Text(
|
||||
'Git Commit: $_gitHash',
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 24),
|
||||
const Text(
|
||||
'Error Details:',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
@@ -76,6 +77,48 @@ void main() {
|
||||
expect(mock.launchedUrl, isNot(contains('Stack%20Trace')));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Copy to Clipboard includes App Version and excludes Git Commit when GIT_HASH is empty',
|
||||
(
|
||||
tester,
|
||||
) async {
|
||||
tester.view.physicalSize = const Size(800, 1200);
|
||||
tester.view.devicePixelRatio = 1.0;
|
||||
addTearDown(() => tester.view.resetPhysicalSize());
|
||||
|
||||
UrlLauncherPlatform.instance = MockUrlLauncher();
|
||||
|
||||
String? capturedClipboard;
|
||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(
|
||||
SystemChannels.platform,
|
||||
(MethodCall call) async {
|
||||
if (call.method == 'Clipboard.setData') {
|
||||
capturedClipboard = (call.arguments as Map)['text'] as String;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
const exception = 'TestException: clipboard test';
|
||||
final stackTrace = StackTrace.current;
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: CrashScreen(exception: exception, stackTrace: stackTrace),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Copy to Clipboard'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(capturedClipboard, isNotNull);
|
||||
expect(capturedClipboard, contains('App Version:'));
|
||||
expect(capturedClipboard, contains('Platform:'));
|
||||
expect(capturedClipboard, contains('TestException: clipboard test'));
|
||||
// GIT_HASH is empty in tests (no --dart-define), so the line is omitted.
|
||||
expect(capturedClipboard, isNot(contains('Git Commit:')));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'CrashScreen used as root widget — buttons work without ScaffoldMessenger crash',
|
||||
(tester) async {
|
||||
|
||||
Reference in New Issue
Block a user