2023-09-06 12:56:30 +03:30
|
|
|
import 'package:dio/dio.dart';
|
2023-12-01 12:56:24 +03:30
|
|
|
import 'package:hiddify/core/localization/translations.dart';
|
2023-07-06 17:18:41 +03:30
|
|
|
|
2023-10-04 18:06:48 +03:30
|
|
|
typedef PresentableError = ({String type, String? message});
|
|
|
|
|
|
2023-07-06 17:18:41 +03:30
|
|
|
mixin Failure {
|
2023-08-26 17:01:51 +03:30
|
|
|
({String type, String? message}) present(TranslationsEn t);
|
2023-07-06 17:18:41 +03:30
|
|
|
}
|
|
|
|
|
|
2023-10-04 18:06:48 +03:30
|
|
|
/// failures that are not expected to happen but depending on [error] type might not be relevant (eg network errors)
|
2023-10-03 21:12:14 +03:30
|
|
|
mixin UnexpectedFailure {
|
|
|
|
|
Object? get error;
|
|
|
|
|
StackTrace? get stackTrace;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-04 18:06:48 +03:30
|
|
|
/// failures that are expected to happen and should be handled by the app
|
|
|
|
|
/// and should be logged, eg missing permissions
|
|
|
|
|
mixin ExpectedMeasuredFailure {}
|
|
|
|
|
|
2023-09-22 14:17:42 +03:30
|
|
|
/// failures ignored by analytics service etc.
|
2023-10-04 18:06:48 +03:30
|
|
|
mixin ExpectedFailure {}
|
2023-09-22 14:17:42 +03:30
|
|
|
|
2023-07-06 17:18:41 +03:30
|
|
|
extension ErrorPresenter on TranslationsEn {
|
2023-10-04 18:06:48 +03:30
|
|
|
PresentableError errorToPair(Object error) => switch (error) {
|
|
|
|
|
UnexpectedFailure(error: final nestedErr?) => errorToPair(nestedErr),
|
|
|
|
|
Failure() => error.present(this),
|
|
|
|
|
DioException() => error.present(this),
|
2024-02-05 17:00:23 +01:00
|
|
|
_ => (type: failure.unexpected, message: error.toString()),
|
2023-10-04 18:06:48 +03:30
|
|
|
};
|
2023-09-06 12:56:30 +03:30
|
|
|
|
2023-10-04 18:06:48 +03:30
|
|
|
PresentableError presentError(
|
2023-10-02 23:57:20 +03:30
|
|
|
Object error, {
|
|
|
|
|
String? action,
|
|
|
|
|
}) {
|
2023-10-04 18:06:48 +03:30
|
|
|
final pair = errorToPair(error);
|
|
|
|
|
if (action == null) return pair;
|
2023-10-02 23:57:20 +03:30
|
|
|
return (
|
2023-10-04 18:06:48 +03:30
|
|
|
type: action,
|
|
|
|
|
message: pair.type + (pair.message == null ? "" : "\n${pair.message!}"),
|
2023-10-02 23:57:20 +03:30
|
|
|
);
|
|
|
|
|
}
|
2023-10-04 18:06:48 +03:30
|
|
|
|
|
|
|
|
String presentShortError(
|
|
|
|
|
Object error, {
|
|
|
|
|
String? action,
|
|
|
|
|
}) {
|
|
|
|
|
final pair = errorToPair(error);
|
|
|
|
|
if (action == null) return pair.type;
|
|
|
|
|
return "$action: ${pair.type}";
|
|
|
|
|
}
|
2023-10-02 23:57:20 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension DioExceptionPresenter on DioException {
|
2023-10-04 18:06:48 +03:30
|
|
|
PresentableError present(TranslationsEn t) => switch (type) {
|
2023-10-02 23:57:20 +03:30
|
|
|
DioExceptionType.connectionTimeout ||
|
|
|
|
|
DioExceptionType.sendTimeout ||
|
|
|
|
|
DioExceptionType.receiveTimeout =>
|
2023-10-04 18:06:48 +03:30
|
|
|
(type: t.failure.connection.timeout, message: null),
|
|
|
|
|
DioExceptionType.badCertificate => (
|
|
|
|
|
type: t.failure.connection.badCertificate,
|
|
|
|
|
message: message,
|
|
|
|
|
),
|
|
|
|
|
DioExceptionType.badResponse => (
|
|
|
|
|
type: t.failure.connection.badResponse,
|
|
|
|
|
message: message,
|
|
|
|
|
),
|
|
|
|
|
DioExceptionType.connectionError => (
|
|
|
|
|
type: t.failure.connection.connectionError,
|
|
|
|
|
message: message,
|
|
|
|
|
),
|
|
|
|
|
_ => (type: t.failure.connection.unexpected, message: message),
|
2023-10-02 23:57:20 +03:30
|
|
|
};
|
2023-07-06 17:18:41 +03:30
|
|
|
}
|