Improve error handling Co-authored-by: Jonas Franz <info@jonasfranz.software> Reviewed-on: #45 Reviewed-by: konrad <konrad@kola-entertainments.de>
This commit is contained in:
parent
6c0762d458
commit
8993999a68
|
@ -53,8 +53,15 @@ class Client {
|
||||||
|
|
||||||
dynamic _handleResponse(http.Response response) {
|
dynamic _handleResponse(http.Response response) {
|
||||||
if (response.statusCode < 200 ||
|
if (response.statusCode < 200 ||
|
||||||
response.statusCode > 400 ||
|
response.statusCode >= 400 ||
|
||||||
json == null) {
|
json == null) {
|
||||||
|
if (response.statusCode ~/ 100 == 4) {
|
||||||
|
Map<String, dynamic> error = _decoder.convert(response.body);
|
||||||
|
throw new InvalidRequestApiException(
|
||||||
|
response.statusCode,
|
||||||
|
response.request.url.toString(),
|
||||||
|
error["message"] ?? "Unknown Error");
|
||||||
|
}
|
||||||
throw new ApiException(
|
throw new ApiException(
|
||||||
response.statusCode, response.request.url.toString());
|
response.statusCode, response.request.url.toString());
|
||||||
}
|
}
|
||||||
|
@ -62,6 +69,17 @@ class Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InvalidRequestApiException extends ApiException {
|
||||||
|
final String message;
|
||||||
|
InvalidRequestApiException(int errorCode, String path, this.message)
|
||||||
|
: super(errorCode, path);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ApiException implements Exception {
|
class ApiException implements Exception {
|
||||||
final int errorCode;
|
final int errorCode;
|
||||||
final String path;
|
final String path;
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ErrorDialog extends StatelessWidget {
|
||||||
|
final dynamic error;
|
||||||
|
|
||||||
|
ErrorDialog({this.error});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
content: Text(error.toString()),
|
||||||
|
actions: <Widget>[
|
||||||
|
FlatButton(
|
||||||
|
child: Text('Close'),
|
||||||
|
onPressed: () => Navigator.of(context).maybePop(),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sentry/sentry.dart';
|
import 'package:sentry/sentry.dart';
|
||||||
import 'package:vikunja_app/constants.dart';
|
import 'package:vikunja_app/constants.dart';
|
||||||
|
@ -9,6 +10,11 @@ import 'package:vikunja_app/pages/user/login.dart';
|
||||||
import 'package:vikunja_app/theme/theme.dart';
|
import 'package:vikunja_app/theme/theme.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
if (!kReleaseMode) {
|
||||||
|
// only log errors in release mode
|
||||||
|
_startApp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
var sentry = new SentryClient(dsn: SENTRY_DSN);
|
var sentry = new SentryClient(dsn: SENTRY_DSN);
|
||||||
|
|
||||||
FlutterError.onError = (details, {bool forceReport = false}) {
|
FlutterError.onError = (details, {bool forceReport = false}) {
|
||||||
|
@ -26,9 +32,7 @@ void main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
runZoned(
|
runZoned(
|
||||||
() => runApp(VikunjaGlobal(
|
_startApp,
|
||||||
child: new VikunjaApp(home: HomePage()),
|
|
||||||
login: new VikunjaApp(home: LoginPage()))),
|
|
||||||
onError: (Object error, StackTrace stackTrace) {
|
onError: (Object error, StackTrace stackTrace) {
|
||||||
try {
|
try {
|
||||||
sentry.captureException(
|
sentry.captureException(
|
||||||
|
@ -44,6 +48,10 @@ void main() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_startApp() => runApp(VikunjaGlobal(
|
||||||
|
child: new VikunjaApp(home: HomePage()),
|
||||||
|
login: new VikunjaApp(home: LoginPage())));
|
||||||
|
|
||||||
class VikunjaApp extends StatelessWidget {
|
class VikunjaApp extends StatelessWidget {
|
||||||
final Widget home;
|
final Widget home;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:after_layout/after_layout.dart';
|
import 'package:after_layout/after_layout.dart';
|
||||||
|
|
||||||
import 'package:vikunja_app/components/AddDialog.dart';
|
import 'package:vikunja_app/components/AddDialog.dart';
|
||||||
|
import 'package:vikunja_app/components/ErrorDialog.dart';
|
||||||
import 'package:vikunja_app/pages/namespace/namespace.dart';
|
import 'package:vikunja_app/pages/namespace/namespace.dart';
|
||||||
import 'package:vikunja_app/pages/namespace/namespace_edit.dart';
|
import 'package:vikunja_app/pages/namespace/namespace_edit.dart';
|
||||||
import 'package:vikunja_app/pages/placeholder.dart';
|
import 'package:vikunja_app/pages/placeholder.dart';
|
||||||
|
@ -162,7 +163,8 @@ class HomePageState extends State<HomePage> with AfterLayoutMixin<HomePage> {
|
||||||
Scaffold.of(context).showSnackBar(SnackBar(
|
Scaffold.of(context).showSnackBar(SnackBar(
|
||||||
content: Text('The namespace was created successfully!'),
|
content: Text('The namespace was created successfully!'),
|
||||||
));
|
));
|
||||||
});
|
}).catchError((error) => showDialog(
|
||||||
|
context: context, builder: (context) => ErrorDialog(error: error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadNamespaces() {
|
Future<void> _loadNamespaces() {
|
||||||
|
|
Reference in New Issue