Skip to content

Commit e3dd562

Browse files
authored
Merge pull request ubuntu#1723 from d-loose/error-view
feat: add custom error view
2 parents b532fa3 + d6bbe1e commit e3dd562

20 files changed

+304
-20
lines changed

packages/app_center/assets/error.svg

Lines changed: 1 addition & 0 deletions
Loading

packages/app_center/lib/deb/deb_page.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:app_center/appstream/appstream.dart';
44
import 'package:app_center/constants.dart';
55
import 'package:app_center/deb/deb_model.dart';
66
import 'package:app_center/deb/deb_providers.dart';
7+
import 'package:app_center/error/error.dart';
78
import 'package:app_center/l10n.dart';
89
import 'package:app_center/layout.dart';
910
import 'package:app_center/packagekit/packagekit.dart';
@@ -59,7 +60,10 @@ class _DebPageState extends ConsumerState<DebPage> {
5960
debModel: debModel,
6061
),
6162
),
62-
error: (error, stackTrace) => ErrorWidget(error),
63+
error: (error, stackTrace) => ErrorView(
64+
error: error,
65+
onRetry: () => ref.invalidate(debModelProvider(widget.id)),
66+
),
6367
loading: () => const Center(child: YaruCircularProgressIndicator()),
6468
);
6569
}

packages/app_center/lib/deb/local_deb_page.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:app_center/constants.dart';
22
import 'package:app_center/deb/local_deb_model.dart';
3+
import 'package:app_center/error/error.dart';
34
import 'package:app_center/l10n.dart';
45
import 'package:app_center/layout.dart';
56
import 'package:app_center/widgets/widgets.dart';
@@ -25,7 +26,10 @@ class LocalDebPage extends ConsumerWidget {
2526
return model.when(
2627
data: (debData) => _LocalDebPage(debData: debData),
2728
loading: () => const Center(child: YaruCircularProgressIndicator()),
28-
error: (error, stackTrace) => ErrorWidget(error),
29+
error: (error, stackTrace) => ErrorView(
30+
error: error,
31+
onRetry: () => ref.invalidate(localDebModelProvider(path: path)),
32+
),
2933
);
3034
}
3135
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
export 'error_l10n.dart';
12
export 'error_observer.dart';
3+
export 'error_view.dart';
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import 'package:app_center/l10n.dart';
2+
import 'package:snapd/snapd.dart';
3+
4+
enum ErrorAction {
5+
retry,
6+
checkStatus,
7+
}
8+
9+
sealed class ErrorMessage {
10+
const ErrorMessage();
11+
12+
factory ErrorMessage.fromObject(Object? e) {
13+
if (e is! SnapdException) return ErrorMessageUnkown();
14+
15+
switch (e.kind) {
16+
case 'network-timeout':
17+
return ErrorMessageNetwork();
18+
}
19+
for (final patternMap in _patternMaps) {
20+
final match = patternMap.pattern.firstMatch(e.message);
21+
if (match != null) {
22+
return patternMap.message(match);
23+
}
24+
}
25+
return ErrorMessageUnkown();
26+
}
27+
28+
static final _patternMaps =
29+
<({RegExp pattern, ErrorMessage Function(Match) message})>[
30+
(
31+
pattern: RegExp('too many requests'),
32+
message: (_) => ErrorMessageTooManyRequests(),
33+
),
34+
(
35+
pattern: RegExp(
36+
r'cannot refresh "(.*?)": snap "\1" has running apps \((.*?)\)',
37+
),
38+
message: (match) => ErrorMessageRunningApps(match.group(1)!),
39+
),
40+
(
41+
pattern: RegExp('persistent network error'),
42+
message: (_) => ErrorMessageNetwork(),
43+
),
44+
];
45+
46+
String body(AppLocalizations l10n) => switch (this) {
47+
ErrorMessageNetwork() => l10n.errorViewNetworkErrorDescription,
48+
ErrorMessageTooManyRequests() => l10n.errorViewServerErrorDescription,
49+
ErrorMessageRunningApps(snap: final snap) =>
50+
l10n.snapdExceptionRunningApps(snap),
51+
_ => l10n.errorViewUnknownErrorDescription,
52+
};
53+
54+
String title(AppLocalizations l10n) => switch (this) {
55+
ErrorMessageNetwork() => l10n.errorViewNetworkErrorTitle,
56+
_ => l10n.errorViewUnknownErrorTitle,
57+
};
58+
59+
String actionLabel(AppLocalizations l10n) => switch (this) {
60+
ErrorMessageNetwork() => l10n.errorViewNetworkErrorAction,
61+
ErrorMessageTooManyRequests() => l10n.errorViewServerErrorAction,
62+
_ => l10n.errorViewUnknownErrorAction,
63+
};
64+
65+
List<ErrorAction> get actions => switch (this) {
66+
ErrorMessageNetwork() => [ErrorAction.retry],
67+
ErrorMessageTooManyRequests() => [ErrorAction.checkStatus],
68+
ErrorMessageRunningApps() => [],
69+
_ => [ErrorAction.retry, ErrorAction.checkStatus],
70+
};
71+
}
72+
73+
class ErrorMessageNetwork extends ErrorMessage {}
74+
75+
class ErrorMessageTooManyRequests extends ErrorMessage {}
76+
77+
class ErrorMessageRunningApps extends ErrorMessage {
78+
const ErrorMessageRunningApps(this.snap);
79+
final String snap;
80+
}
81+
82+
class ErrorMessageUnkown extends ErrorMessage {}

0 commit comments

Comments
 (0)