Surface persistence and fetch errors instead of swallowing them

PrefUtil.setValue now returns the underlying SharedPreferences result
and throws on unsupported types; settings save reports failures rather
than always showing success. Device detail and event history report
the real Dio error message and skip cancellations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
rzuasti
2026-05-31 18:43:46 -04:00
co-authored by Claude Sonnet 4.6
parent f7f255e20f
commit e70676a193
5 changed files with 47 additions and 21 deletions
+14 -4
View File
@@ -1,3 +1,4 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
@@ -42,8 +43,9 @@ class _DeviceDetailState extends State<DeviceDetail> {
});
} catch (e) {
if (!mounted) return;
if (e is DioException && e.type == DioExceptionType.cancel) return;
setState(() {
_error = e.toString();
_error = dioErrorToUserMessage(e);
_isLoading = false;
});
}
@@ -140,7 +142,10 @@ class _DeviceHeader extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectableText(device.ipv4Address, style: theme.textTheme.headlineSmall),
SelectableText(
device.ipv4Address,
style: theme.textTheme.headlineSmall,
),
const SizedBox(height: 4),
if (device.isRegistered)
StatusBadge(label: 'Registered', color: BadgeColor.success)
@@ -166,7 +171,10 @@ class _DeviceInfoCard extends StatelessWidget {
Widget build(BuildContext context) {
final formatter = FriendlyDateFormatter();
final rows = <(String, String)>[
('Name', device.name == null || device.name!.isEmpty ? '' : device.name!),
(
'Name',
device.name == null || device.name!.isEmpty ? '' : device.name!,
),
('MAC Address', device.macAddress),
('IP Address', device.ipv4Address),
('Vendor', device.vendor.isEmpty ? '' : device.vendor),
@@ -251,7 +259,9 @@ class _InfoRow extends StatelessWidget {
),
),
),
Expanded(child: SelectableText(value, style: theme.textTheme.bodyMedium)),
Expanded(
child: SelectableText(value, style: theme.textTheme.bodyMedium),
),
],
),
);
@@ -1,3 +1,4 @@
import 'package:dio/dio.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
@@ -98,8 +99,9 @@ class _DeviceEventHistoryState extends State<DeviceEventHistory> {
});
} catch (e) {
if (!mounted) return;
if (e is DioException && e.type == DioExceptionType.cancel) return;
setState(() {
_error = e.toString();
_error = dioErrorToUserMessage(e);
_isLoading = false;
});
}
@@ -115,9 +117,9 @@ class _DeviceEventHistoryState extends State<DeviceEventHistory> {
}
if (_error != null) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Center(child: Text('Failed to load event history')),
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Center(child: Text('Failed to load event history: $_error')),
);
}