From 8274dd46cd3aaa1ba595157ce65aa839f4eccca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Mon, 13 Jul 2026 22:58:02 +0200 Subject: [PATCH] refactored HTTP error handling and streamlined UI components by centralizing shared logic and removing redundant parameters --- lib/api/api_request.dart | 1 - lib/api/errors/error_mapper.dart | 6 +- lib/api/http_errors.dart | 53 +++++++++ .../cloud_users/cloud_users_actions.dart | 32 ++---- .../talk/chat/long_poll_chat.dart | 21 +--- lib/api/marianumcloud/talk/talk_api.dart | 53 +++------ lib/api/marianumcloud/webdav/webdav_api.dart | 3 +- lib/api/mhsl/mhsl_api.dart | 35 ++---- lib/app.dart | 4 +- .../data_loader/data_loader.dart | 45 -------- .../loadable_state/loadable_state.dart | 9 +- lib/utils/downloads/download_manager.dart | 12 +- .../pages/files/widgets/file_element.dart | 25 ++--- .../chat_background_settings_page.dart | 64 +++++------ lib/view/pages/talk/chat_view.dart | 3 - .../pages/talk/data/chat_bubble_styles.dart | 38 +++---- .../pages/talk/widgets/answer_reference.dart | 6 +- lib/view/pages/talk/widgets/chat_bubble.dart | 7 +- .../pages/talk/widgets/chat_textfield.dart | 1 - .../widgets/calendar/outside_chips.dart | 37 +----- .../timetable/widgets/calendar/week_grid.dart | 83 ++++++++------ .../widgets/timetable_calendar_view.dart | 3 - .../async_actions/async_dialog_action.dart | 3 - lib/widget/avatar_actions_sheet.dart | 106 ++++++++---------- lib/widget/chat_background_picker_sheet.dart | 61 ++++------ lib/widget/debug/cache_view.dart | 1 - lib/widget/debug/debug_tile.dart | 3 +- lib/widget/debug/json_viewer.dart | 16 +-- 28 files changed, 284 insertions(+), 447 deletions(-) delete mode 100644 lib/api/api_request.dart create mode 100644 lib/api/http_errors.dart delete mode 100644 lib/state/app/infrastructure/data_loader/data_loader.dart diff --git a/lib/api/api_request.dart b/lib/api/api_request.dart deleted file mode 100644 index 2cdf97c..0000000 --- a/lib/api/api_request.dart +++ /dev/null @@ -1 +0,0 @@ -class ApiRequest {} diff --git a/lib/api/errors/error_mapper.dart b/lib/api/errors/error_mapper.dart index 7fb4a9d..9cafa3a 100644 --- a/lib/api/errors/error_mapper.dart +++ b/lib/api/errors/error_mapper.dart @@ -6,6 +6,7 @@ import 'package:http/http.dart' as http; import 'package:nextcloud/nextcloud.dart'; import '../api_error.dart'; +import '../http_errors.dart'; import '../marianumcloud/talk/talk_error.dart'; import 'app_exception.dart'; import 'auth_exception.dart'; @@ -59,9 +60,8 @@ AppException? _dioToAppException(DioException error) { /// status plus a trimmed body preview (same format as the Talk API errors). AppException _dynamiteToAppException(DynamiteApiException error) { final status = error.statusCode; - final body = error.body.replaceAll(RegExp(r'\s+'), ' ').trim(); - final preview = body.length > 500 ? '${body.substring(0, 500)}…' : body; - final detail = body.isEmpty ? 'HTTP $status' : 'HTTP $status body=$preview'; + final preview = previewBody(error.body); + final detail = preview.isEmpty ? 'HTTP $status' : 'HTTP $status body=$preview'; switch (status) { case 401: return AuthException.unauthorized(technicalDetails: detail); diff --git a/lib/api/http_errors.dart b/lib/api/http_errors.dart new file mode 100644 index 0000000..f45f770 --- /dev/null +++ b/lib/api/http_errors.dart @@ -0,0 +1,53 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:http/http.dart' as http; + +import 'errors/auth_exception.dart'; +import 'errors/network_exception.dart'; +import 'errors/not_found_exception.dart'; +import 'errors/server_exception.dart'; + +/// Runs [send] and converts transport-level failures (socket/timeout/client +/// errors) into a [NetworkException] tagged with [label] (e.g. `Talk `). +/// Passes through whatever [send] produces, including `null` for the base-class +/// request hooks that may skip the call. +Future sendGuarded( + String label, + Future? Function() send, +) async { + try { + return await send(); + } on SocketException catch (e) { + throw NetworkException(technicalDetails: '$label: ${e.message}'); + } on TimeoutException catch (e) { + throw NetworkException.timeout(technicalDetails: '$label: $e'); + } on http.ClientException catch (e) { + throw NetworkException(technicalDetails: '$label: ${e.message}'); + } +} + +/// Collapses whitespace and caps an HTTP error body at 500 chars so it can be +/// embedded in an [AppException]'s technical details without dumping headers. +String previewBody(String body) { + final collapsed = body.replaceAll(RegExp(r'\s+'), ' ').trim(); + return collapsed.length > 500 ? '${collapsed.substring(0, 500)}…' : collapsed; +} + +/// Builds a `