feat: surface read-only load errors
This commit is contained in:
55
lib/app/error_message.dart
Normal file
55
lib/app/error_message.dart
Normal file
@@ -0,0 +1,55 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
String describeLoadError(Object error) {
|
||||
if (error is DioException) {
|
||||
final statusCode = error.response?.statusCode;
|
||||
|
||||
if (statusCode == 401 || statusCode == 403) {
|
||||
return 'Нет доступа: API key отклонён ($statusCode).';
|
||||
}
|
||||
|
||||
if (_isNetworkFailure(error)) {
|
||||
return 'Backend недоступен: ${error.message ?? error.type.name}.';
|
||||
}
|
||||
|
||||
final responseMessage = _responseMessage(error);
|
||||
if (responseMessage != null) {
|
||||
return 'Backend вернул ошибку $statusCode: $responseMessage';
|
||||
}
|
||||
|
||||
if (statusCode != null) {
|
||||
return 'Backend вернул ошибку $statusCode.';
|
||||
}
|
||||
|
||||
return 'Ошибка запроса: ${error.message ?? error.type.name}.';
|
||||
}
|
||||
|
||||
if (error is FormatException) {
|
||||
return 'Неожиданный ответ backend: ${error.message}';
|
||||
}
|
||||
|
||||
return error.toString();
|
||||
}
|
||||
|
||||
bool _isNetworkFailure(DioException error) {
|
||||
return switch (error.type) {
|
||||
DioExceptionType.connectionTimeout ||
|
||||
DioExceptionType.sendTimeout ||
|
||||
DioExceptionType.receiveTimeout ||
|
||||
DioExceptionType.connectionError ||
|
||||
DioExceptionType.unknown => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
String? _responseMessage(DioException error) {
|
||||
final data = error.response?.data;
|
||||
if (data is Map) {
|
||||
final value = data['detail'] ?? data['message'] ?? data['error'];
|
||||
return value?.toString();
|
||||
}
|
||||
if (data is String && data.trim().isNotEmpty) {
|
||||
return data.trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user