add error observer

fdroid
Kherel 2021-01-13 17:45:46 +01:00
parent a8262229c0
commit cf6e0b3495
10 changed files with 91 additions and 8 deletions

View File

@ -1,5 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pro.kherel.selfprivacy">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide

View File

@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/ui/components/error/error.dart';
import 'package:selfprivacy/utils/route_transitions/basic.dart';
class SimpleBlocObserver extends BlocObserver {
final GlobalKey<NavigatorState> navigatorKey;
SimpleBlocObserver({this.navigatorKey});
@override
void onError(Cubit cubit, Object error, StackTrace stackTrace) {
navigatorKey.currentState.push(
materialRoute(
BrandError(
error: error,
stackTrace: stackTrace,
),
),
);
super.onError(cubit, error, stackTrace);
}
}

View File

@ -30,7 +30,7 @@ class CloudflareApi extends ApiMap {
} else if (response.statusCode == HttpStatus.unauthorized) {
return false;
} else {
throw Exception('something bad happend');
throw Exception('code: ${response.statusCode}');
}
}

View File

@ -14,7 +14,7 @@ class HetznerApi extends ApiMap {
}
@override
String rootAddress = 'https://api.hetzner.cloud/v1/servers';
String rootAddress = 'http://api.hetzner.cloud/v1/servers';
Future<bool> isValid(String token) async {
var options = Options(
@ -31,7 +31,7 @@ class HetznerApi extends ApiMap {
} else if (response.statusCode == HttpStatus.unauthorized) {
return false;
} else {
throw Exception('something bad happend');
throw Exception('code: ${response.statusCode}');
}
}
@ -44,7 +44,7 @@ class HetznerApi extends ApiMap {
"server_type": "cx11",
"start_after_create": true,
"image": "ubuntu-20.04",
"ssh_keys": [],
"ssh_keys": ["ilchub"],
"volumes": [],
"networks": [],
'user-data':

View File

@ -23,7 +23,6 @@ class AppSettingsCubit extends Cubit<AppSettingsState> {
void load() {
bool isDarkModeOn = box.get(BNames.isDarkModeOn);
bool isOnbordingShowing = box.get(BNames.isOnbordingShowing);
emit(state.copyWith(
isDarkModeOn: isDarkModeOn,
isOnbordingShowing: isOnbordingShowing,

View File

@ -34,7 +34,13 @@ class CloudFlareFormCubit extends FormCubit {
@override
FutureOr<bool> asyncValidation() async {
var isKeyValid = await apiClient.isValid(apiKey.state.value);
bool isKeyValid;
try {
isKeyValid = await apiClient.isValid(apiKey.state.value);
} catch (e) {
addError(e);
}
if (!isKeyValid) {
apiKey.setError('bad key');

View File

@ -41,7 +41,13 @@ class DomainFormCubit extends FormCubit {
FutureOr<bool> asyncValidation() async {
var key = initializingCubit.state.cloudFlareKey;
var zoneId = await apiClient.getZoneId(key, domainName.state.value);
String zoneId;
try {
zoneId = await apiClient.getZoneId(key, domainName.state.value);
} catch (e) {
addError(e);
}
if (zoneId == null) {
domainName.setError('Domain not in the list');

View File

@ -34,7 +34,12 @@ class HetznerFormCubit extends FormCubit {
@override
FutureOr<bool> asyncValidation() async {
var isKeyValid = await apiClient.isValid(apiKey.state.value);
bool isKeyValid;
try {
isKeyValid = await apiClient.isValid(apiKey.state.value);
} catch (e) {
addError(e);
}
if (!isKeyValid) {
apiKey.setError('bad key');

View File

@ -1,17 +1,22 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/config/hive_config.dart';
import 'package:selfprivacy/ui/pages/initializing/initializing.dart';
import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:selfprivacy/ui/pages/rootRoute.dart';
import 'config/bloc_config.dart';
import 'config/bloc_observer.dart';
import 'config/brand_theme.dart';
import 'config/localization.dart';
import 'logic/cubit/app_settings/app_settings_cubit.dart';
final navigatorKey = GlobalKey<NavigatorState>();
void main() async {
await HiveConfig.init();
Bloc.observer = SimpleBlocObserver(navigatorKey: navigatorKey);
WidgetsFlutterBinding.ensureInitialized();
@ -32,6 +37,7 @@ class MyApp extends StatelessWidget {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light, // Manually changnig appbar color
child: MaterialApp(
navigatorKey: navigatorKey,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
@ -41,6 +47,13 @@ class MyApp extends StatelessWidget {
home: appSettings.isOnbordingShowing
? OnboardingPage(nextPage: InitializingPage())
: RootPage(),
builder: (BuildContext context, Widget widget) {
Widget error = Text('...rendering error...');
if (widget is Scaffold || widget is Navigator)
error = Scaffold(body: Center(child: error));
ErrorWidget.builder = (FlutterErrorDetails errorDetails) => error;
return widget;
},
),
);
}

View File

@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class BrandError extends StatelessWidget {
const BrandError({Key key, this.error, this.stackTrace}) : super(key: key);
final Object error;
final StackTrace stackTrace;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Center(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(error.toString()),
Text('stackTrace: '),
Text(stackTrace.toString()),
],
),
),
),
),
);
}
}