From b0021f82aceac38e482eb6f906912cb21eaf7744 Mon Sep 17 00:00:00 2001 From: lemoer Date: Sat, 19 Jul 2025 11:06:03 +0200 Subject: [PATCH] Catch exceptions and show them in logs --- lib/main.dart | 72 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 4 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 9daed7b..f6c435a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:ui'; import 'package:dartssh2/dartssh2.dart'; import 'package:flutter/material.dart'; @@ -21,6 +22,21 @@ import 'authentik_api.dart' as authentik; import 'package:app_links/app_links.dart'; void main() { + final errorNotifier = ValueNotifier(null); + + // Fehler-Handler registrieren + PlatformDispatcher.instance.onError = (error, stack) { + final timeStr = DateTime.now().toIso8601String(); + final errorMessage = 'Time: $timeStr\nError: $error\nStack: $stack'; + + if (errorNotifier.value == null) { + errorNotifier.value = errorMessage; + } else { + errorNotifier.value = errorNotifier.value! + '\n\n' + errorMessage; + } + return true; + }; + runApp( MultiProvider( providers: [ @@ -28,7 +44,7 @@ void main() { create: (context) => AuthentikUserSettingsChangeDialogState(), ), // Do something (navigation, ...) ], - child: const MyApp(), + child: MyApp(errorNotifier: errorNotifier), ), ); } @@ -57,7 +73,9 @@ String encodePublicKey(OpenSSHEd25519KeyPair keyPair, {String comment = ''}) { } class MyApp extends StatelessWidget { - const MyApp({super.key}); + final ValueNotifier errorNotifier; + + const MyApp({super.key, required this.errorNotifier}); @override Widget build(BuildContext context) { @@ -66,15 +84,23 @@ class MyApp extends StatelessWidget { theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.yellow), ), - home: const MyHomePage(title: 'LeineLab e.V. Key App'), + home: MyHomePage( + title: 'LeineLab e.V. Key App', + errorNotifier: errorNotifier, + ), ); } } class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); + const MyHomePage({ + super.key, + required this.title, + required this.errorNotifier, + }); final String title; + final ValueNotifier errorNotifier; @override State createState() => _MyHomePageState(); @@ -402,6 +428,31 @@ class _MyHomePageState extends State { ), ); + final bodyComponentLogs = Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.all(20), + child: Card( + child: ValueListenableBuilder( + valueListenable: widget.errorNotifier, + builder: (context, error, child) { + if (error != null) { + return Text( + "Error: $error", + style: TextStyle(color: Colors.red, fontSize: 15), + ); + } + return Text("No exceptions captured yet."); + }, + ), + ), + ), + ], + ), + ); + final actionButtonInfo = FloatingActionButton( onPressed: () => obtainKeyPair(regenerate: true), tooltip: 'Regenerate Key', @@ -419,6 +470,10 @@ class _MyHomePageState extends State { // Info page bodyComponent = bodyComponentInfo; actionButton = actionButtonInfo; + } else if (navIndex == 2) { + // Logs page + bodyComponent = bodyComponentLogs; + actionButton = null; } else { throw Exception('Unknown navIndex: $navIndex'); } @@ -456,6 +511,15 @@ class _MyHomePageState extends State { Navigator.pop(context); }, ), + ListTile( + title: const Text('Logs'), + onTap: () { + setState(() { + navIndex = 2; + }); + Navigator.pop(context); + }, + ), ], ), ),