mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-23 09:16:54 +00:00
feat: Implement critical error handling page
Now when we can't handle an exception, application redirects user to a new ErrorPage where they can copy stacktrace, logs and share to our support chat
This commit is contained in:
parent
0df5940c68
commit
3a5cb0f81b
|
@ -1,6 +1,11 @@
|
|||
{
|
||||
"test": "en-test",
|
||||
"locale": "en",
|
||||
"error": {
|
||||
"page_title": "Oops, something happened...",
|
||||
"page_description": "We couldn't handle an exception, but it is important for us to know what just happened. Please share this log to our support!",
|
||||
"page_share": "Share:"
|
||||
},
|
||||
"basis": {
|
||||
"providers": "Providers",
|
||||
"providers_title": "Your Data Center",
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
{
|
||||
"test": "ru-test",
|
||||
"locale": "ru",
|
||||
"error": {
|
||||
"page_title": "Упс, что-то случилось...",
|
||||
"page_description": "Нам не удалось обработать исключение, но нам важно знать, что только что произошло. Пожалуйста, отправьте нашей поддержке данный лог!",
|
||||
"page_share": "Поделиться:"
|
||||
},
|
||||
"basis": {
|
||||
"providers": "Провайдеры",
|
||||
"providers_title": "Ваш Дата Центр",
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:selfprivacy/config/brand_colors.dart';
|
||||
import 'package:selfprivacy/config/hive_config.dart';
|
||||
import 'package:selfprivacy/theming/factory/app_theme_factory.dart';
|
||||
import 'package:selfprivacy/ui/pages/error_page.dart';
|
||||
import 'package:selfprivacy/ui/pages/setup/initializing.dart';
|
||||
import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
|
||||
import 'package:selfprivacy/ui/pages/root_route.dart';
|
||||
|
@ -93,13 +95,15 @@ class MyApp extends StatelessWidget {
|
|||
? const OnboardingPage(nextPage: InitializingPage())
|
||||
: const RootPage(),
|
||||
builder: (final BuildContext context, final Widget? widget) {
|
||||
Widget error = const Text('...rendering error...');
|
||||
if (widget is Scaffold || widget is Navigator) {
|
||||
error = Scaffold(body: Center(child: error));
|
||||
}
|
||||
ErrorWidget.builder =
|
||||
(final FlutterErrorDetails errorDetails) => error;
|
||||
return widget!;
|
||||
(final FlutterErrorDetails errorDetails) => ErrorPage(
|
||||
log:
|
||||
'${errorDetails.stack?.toString() ?? ''}\n\n${errorDetails.exception}',
|
||||
);
|
||||
if (widget != null) {
|
||||
return widget;
|
||||
}
|
||||
throw 'widget is null';
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
53
lib/ui/pages/error_page.dart
Normal file
53
lib/ui/pages/error_page.dart
Normal file
|
@ -0,0 +1,53 @@
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/config/brand_theme.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_hero_screen/brand_hero_screen.dart';
|
||||
import 'package:selfprivacy/utils/ui_helpers.dart';
|
||||
|
||||
class ErrorPage extends StatelessWidget {
|
||||
const ErrorPage({required this.log, super.key});
|
||||
|
||||
final String log;
|
||||
final String telegramUrl = 'https://t.me/selfprivacy';
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => BrandHeroScreen(
|
||||
heroTitle: 'error.page_title'.tr(),
|
||||
heroSubtitle: 'error.page_description'.tr(),
|
||||
hasBackButton: false,
|
||||
hasFlashButton: false,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 320,
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.content_copy_outlined),
|
||||
onPressed: () async => Clipboard.setData(
|
||||
ClipboardData(text: log),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 48),
|
||||
Text('error.page_share'.tr()),
|
||||
const SizedBox(width: 16),
|
||||
InkWell(
|
||||
onTap: () async => UiHelpers.launchExternalApplicationURL(
|
||||
telegramUrl,
|
||||
),
|
||||
child: const Icon(Icons.telegram_outlined),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
log,
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
fontFamily: 'RobotoMono',
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
|
@ -33,6 +33,18 @@ class MorePage extends StatelessWidget {
|
|||
final bool? usesBinds =
|
||||
context.watch<ApiServerVolumeCubit>().state.usesBinds;
|
||||
|
||||
return ListView(
|
||||
children: [
|
||||
ListView(
|
||||
children: [
|
||||
Row(
|
||||
children: [Text("jfkhskdjfhdkjs")],
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
/*
|
||||
return Scaffold(
|
||||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(52),
|
||||
|
@ -132,7 +144,7 @@ class MorePage extends StatelessWidget {
|
|||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
); */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue