refactored HTTP error handling and streamlined UI components by centralizing shared logic and removing redundant parameters
This commit is contained in:
@@ -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 <uri>`).
|
||||
/// Passes through whatever [send] produces, including `null` for the base-class
|
||||
/// request hooks that may skip the call.
|
||||
Future<http.Response?> sendGuarded(
|
||||
String label,
|
||||
Future<http.Response>? 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 `<label> -> HTTP <status>[ body=<preview>]` technical detail line.
|
||||
String httpErrorDetail(String label, String body, int status) {
|
||||
final preview = previewBody(body);
|
||||
return preview.isEmpty
|
||||
? '$label -> HTTP $status'
|
||||
: '$label -> HTTP $status body=$preview';
|
||||
}
|
||||
|
||||
/// Throws the [AppException] matching a non-2xx HTTP [status], carrying
|
||||
/// [detail] as technical details: 401/403 map to auth errors, 404 to
|
||||
/// not-found, everything else to a generic server error.
|
||||
Never throwForStatus(int status, String detail) {
|
||||
if (status == 401) throw AuthException.unauthorized(technicalDetails: detail);
|
||||
if (status == 403) throw AuthException.forbidden(technicalDetails: detail);
|
||||
if (status == 404) throw NotFoundException(technicalDetails: detail);
|
||||
throw ServerException(statusCode: status, technicalDetails: detail);
|
||||
}
|
||||
Reference in New Issue
Block a user