add error observer
This commit is contained in:
parent
a8262229c0
commit
cf6e0b3495
|
@ -1,5 +1,7 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="pro.kherel.selfprivacy">
|
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
|
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||||
In most cases you can leave this as-is, but you if you want to provide
|
In most cases you can leave this as-is, but you if you want to provide
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ class CloudflareApi extends ApiMap {
|
||||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw Exception('something bad happend');
|
throw Exception('code: ${response.statusCode}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ class HetznerApi extends ApiMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String rootAddress = 'https://api.hetzner.cloud/v1/servers';
|
String rootAddress = 'http://api.hetzner.cloud/v1/servers';
|
||||||
|
|
||||||
Future<bool> isValid(String token) async {
|
Future<bool> isValid(String token) async {
|
||||||
var options = Options(
|
var options = Options(
|
||||||
|
@ -31,7 +31,7 @@ class HetznerApi extends ApiMap {
|
||||||
} else if (response.statusCode == HttpStatus.unauthorized) {
|
} else if (response.statusCode == HttpStatus.unauthorized) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
throw Exception('something bad happend');
|
throw Exception('code: ${response.statusCode}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ class HetznerApi extends ApiMap {
|
||||||
"server_type": "cx11",
|
"server_type": "cx11",
|
||||||
"start_after_create": true,
|
"start_after_create": true,
|
||||||
"image": "ubuntu-20.04",
|
"image": "ubuntu-20.04",
|
||||||
"ssh_keys": [],
|
"ssh_keys": ["ilchub"],
|
||||||
"volumes": [],
|
"volumes": [],
|
||||||
"networks": [],
|
"networks": [],
|
||||||
'user-data':
|
'user-data':
|
||||||
|
|
|
@ -23,7 +23,6 @@ class AppSettingsCubit extends Cubit<AppSettingsState> {
|
||||||
void load() {
|
void load() {
|
||||||
bool isDarkModeOn = box.get(BNames.isDarkModeOn);
|
bool isDarkModeOn = box.get(BNames.isDarkModeOn);
|
||||||
bool isOnbordingShowing = box.get(BNames.isOnbordingShowing);
|
bool isOnbordingShowing = box.get(BNames.isOnbordingShowing);
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
isDarkModeOn: isDarkModeOn,
|
isDarkModeOn: isDarkModeOn,
|
||||||
isOnbordingShowing: isOnbordingShowing,
|
isOnbordingShowing: isOnbordingShowing,
|
||||||
|
|
|
@ -34,7 +34,13 @@ class CloudFlareFormCubit extends FormCubit {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<bool> asyncValidation() async {
|
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) {
|
if (!isKeyValid) {
|
||||||
apiKey.setError('bad key');
|
apiKey.setError('bad key');
|
||||||
|
|
|
@ -41,7 +41,13 @@ class DomainFormCubit extends FormCubit {
|
||||||
FutureOr<bool> asyncValidation() async {
|
FutureOr<bool> asyncValidation() async {
|
||||||
var key = initializingCubit.state.cloudFlareKey;
|
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) {
|
if (zoneId == null) {
|
||||||
domainName.setError('Domain not in the list');
|
domainName.setError('Domain not in the list');
|
||||||
|
|
|
@ -34,7 +34,12 @@ class HetznerFormCubit extends FormCubit {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<bool> asyncValidation() async {
|
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) {
|
if (!isKeyValid) {
|
||||||
apiKey.setError('bad key');
|
apiKey.setError('bad key');
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:selfprivacy/config/hive_config.dart';
|
import 'package:selfprivacy/config/hive_config.dart';
|
||||||
import 'package:selfprivacy/ui/pages/initializing/initializing.dart';
|
import 'package:selfprivacy/ui/pages/initializing/initializing.dart';
|
||||||
import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
|
import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
import 'package:selfprivacy/ui/pages/rootRoute.dart';
|
||||||
import 'config/bloc_config.dart';
|
import 'config/bloc_config.dart';
|
||||||
|
import 'config/bloc_observer.dart';
|
||||||
import 'config/brand_theme.dart';
|
import 'config/brand_theme.dart';
|
||||||
import 'config/localization.dart';
|
import 'config/localization.dart';
|
||||||
import 'logic/cubit/app_settings/app_settings_cubit.dart';
|
import 'logic/cubit/app_settings/app_settings_cubit.dart';
|
||||||
|
|
||||||
|
final navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
await HiveConfig.init();
|
await HiveConfig.init();
|
||||||
|
Bloc.observer = SimpleBlocObserver(navigatorKey: navigatorKey);
|
||||||
|
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
@ -32,6 +37,7 @@ class MyApp extends StatelessWidget {
|
||||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||||
value: SystemUiOverlayStyle.light, // Manually changnig appbar color
|
value: SystemUiOverlayStyle.light, // Manually changnig appbar color
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
|
navigatorKey: navigatorKey,
|
||||||
localizationsDelegates: context.localizationDelegates,
|
localizationsDelegates: context.localizationDelegates,
|
||||||
supportedLocales: context.supportedLocales,
|
supportedLocales: context.supportedLocales,
|
||||||
locale: context.locale,
|
locale: context.locale,
|
||||||
|
@ -41,6 +47,13 @@ class MyApp extends StatelessWidget {
|
||||||
home: appSettings.isOnbordingShowing
|
home: appSettings.isOnbordingShowing
|
||||||
? OnboardingPage(nextPage: InitializingPage())
|
? OnboardingPage(nextPage: InitializingPage())
|
||||||
: RootPage(),
|
: 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;
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue