mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-09-20 18:37:50 +00:00
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"
|
||||
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
|
||||
|
|
23
lib/config/bloc_observer.dart
Normal file
23
lib/config/bloc_observer.dart
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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}');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
29
lib/ui/components/error/error.dart
Normal file
29
lib/ui/components/error/error.dart
Normal 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()),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue