TF-196 Implement RemoteExceptionThrower when get session

This commit is contained in:
dab246
2022-06-22 11:26:43 +07:00
committed by Dat H. Pham
parent fd9b7cbb0a
commit 4cff46623c
12 changed files with 117 additions and 27 deletions
@@ -5,9 +5,20 @@ import 'package:dio/dio.dart';
class RemoteExceptionThrower {
void throwRemoteException(dynamic exception, {Function(DioError)? handler}) {
if (exception is DioError) {
handler != null ? handler(exception) : throw UnknownError(exception.message);
switch (exception.type) {
case DioErrorType.connectTimeout:
throw ConnectError();
default:
if (handler != null) {
throw handler(exception);
} else {
throw UnknownError(
code: exception.response?.statusCode,
message: exception.message);
}
}
} else {
throw UnknownError(exception.toString());
throw UnknownError(message: exception.toString());
}
}
}
@@ -2,14 +2,23 @@
import 'package:equatable/equatable.dart';
abstract class RemoteException extends Equatable implements Exception {
static final connectError = 'Connect error';
final String? message;
final int? code;
RemoteException(this.message);
RemoteException({this.code, this.message});
}
class UnknownError extends RemoteException {
UnknownError(String? message) : super(message);
UnknownError({int? code, String? message}) : super(code: code, message: message);
@override
List<Object> get props => [];
}
class ConnectError extends RemoteException {
ConnectError() : super(message: RemoteException.connectError);
@override
List<Object> get props => [];
@@ -1,17 +1,26 @@
import 'package:equatable/equatable.dart';
abstract class AuthenticationException extends Equatable {
import 'package:core/domain/exceptions/remote_exception.dart';
abstract class AuthenticationException extends RemoteException {
static const wrongCredential = 'Credential is wrong';
static const badGateway = 'Bad gateway';
static const invalidBaseUrl = 'Invalid base URL';
const AuthenticationException(String message);
AuthenticationException(String message) : super(message: message);
}
class BadCredentials extends AuthenticationException {
const BadCredentials() : super(AuthenticationException.wrongCredential);
BadCredentials() : super(AuthenticationException.wrongCredential);
@override
List<Object> get props => [];
List<Object?> get props => [message];
}
class BadGateway extends AuthenticationException {
BadGateway() : super(AuthenticationException.badGateway);
@override
List<Object?> get props => [message];
}
class NotFoundAuthenticatedAccountException implements Exception {
@@ -23,10 +32,10 @@ class NotFoundStoredTokenException implements Exception {
}
class InvalidBaseUrl extends AuthenticationException {
const InvalidBaseUrl() : super(AuthenticationException.invalidBaseUrl);
InvalidBaseUrl() : super(AuthenticationException.invalidBaseUrl);
@override
List<Object?> get props => [];
List<Object?> get props => [message];
}
class NotFoundAccessTokenException implements Exception {
@@ -20,7 +20,7 @@ class GetCredentialInteractor {
if (isCredentialValid(baseUrl)) {
return Right(GetCredentialViewState(baseUrl, userName, password));
} else {
return Left(GetCredentialFailure(const BadCredentials()));
return Left(GetCredentialFailure(BadCredentials()));
}
} catch (exception) {
return Left(GetCredentialFailure(exception));
@@ -35,7 +35,7 @@ class GetStoredTokenOidcInteractor {
if (_isCredentialValid(baseUrl)) {
yield Right(GetStoredTokenOidcSuccess(baseUrl, tokenOidc, oidcConfiguration));
} else {
yield Left(GetStoredTokenOidcFailure(const InvalidBaseUrl()));
yield Left(GetStoredTokenOidcFailure(InvalidBaseUrl()));
}
} catch (e) {
log('GetStoredTokenOidcInteractor::execute(): $e');
@@ -1,19 +1,34 @@
import 'package:core/data/network/remote_exception_thrower.dart';
import 'package:core/domain/exceptions/remote_exception.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dio/dio.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart';
import 'package:tmail_ui_user/features/session/data/datasource/session_datasource.dart';
import 'package:tmail_ui_user/features/session/data/network/session_api.dart';
class SessionDataSourceImpl extends SessionDataSource {
final SessionAPI sessionAPI;
final SessionAPI _sessionAPI;
final RemoteExceptionThrower _remoteExceptionThrower;
SessionDataSourceImpl(this.sessionAPI);
SessionDataSourceImpl(this._sessionAPI, this._remoteExceptionThrower);
@override
Future<Session> getSession() {
return Future.sync(() async {
return await sessionAPI.getSession();
return await _sessionAPI.getSession();
}).catchError((error) {
throw error;
_remoteExceptionThrower.throwRemoteException(error, handler: (DioError error) {
if (error.response?.statusCode == 502) {
throw BadGateway();
} else {
log('SessionDataSourceImpl::getSession(): statusMessage: ${error.response?.statusMessage}');
throw UnknownError(
code: error.response?.statusCode,
message: error.response?.statusMessage);
}
});
});
}
}
@@ -1,10 +1,15 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/domain/exceptions/remote_exception.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/login/data/network/config/authorization_interceptors.dart';
import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oidc_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
import 'package:tmail_ui_user/features/session/domain/state/get_session_state.dart';
import 'package:tmail_ui_user/features/session/domain/usecases/get_session_interactor.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
@@ -14,6 +19,7 @@ class SessionController extends GetxController {
final CachingManager _cachingManager;
final DeleteAuthorityOidcInteractor _deleteAuthorityOidcInteractor;
final AuthorizationInterceptors _authorizationInterceptors;
final AppToast _appToast;
SessionController(
this._getSessionInteractor,
@@ -21,7 +27,7 @@ class SessionController extends GetxController {
this._cachingManager,
this._deleteAuthorityOidcInteractor,
this._authorizationInterceptors,
);
this._appToast);
@override
void onReady() {
@@ -32,8 +38,32 @@ class SessionController extends GetxController {
void _getSession() async {
await _getSessionInteractor.execute()
.then((response) => response.fold(
(failure) => _goToLogin(),
(success) => success is GetSessionSuccess ? _goToMailboxDashBoard(success) : _goToLogin()));
(failure) {
_handleSessionFailure(failure);
_goToLogin();
},
(success) => success is GetSessionSuccess
? _goToMailboxDashBoard(success)
: _goToLogin()));
}
void _handleSessionFailure(Failure failure) {
if (failure is GetSessionFailure) {
final sessionException = failure.exception;
if (_checkUrlError(sessionException) && currentContext != null) {
_appToast.showErrorToast(AppLocalizations.of(currentContext!).wrongUrlMessage);
} else if (sessionException is UnknownError && currentContext != null) {
if (sessionException.message != null) {
_appToast.showErrorToast('[${sessionException.code}] ${sessionException.message}');
} else {
_appToast.showErrorToast(AppLocalizations.of(currentContext!).unknown_error_login_message);
}
}
}
}
bool _checkUrlError(dynamic sessionException) {
return sessionException is ConnectError || sessionException is BadGateway;
}
void _goToLogin() async {
@@ -1,3 +1,4 @@
import 'package:core/presentation/utils/app_toast.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/base_bindings.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
@@ -25,6 +26,7 @@ class SessionPageBindings extends BaseBindings {
Get.find<CachingManager>(),
Get.find<DeleteAuthorityOidcInteractor>(),
Get.find<AuthorizationInterceptors>(),
Get.find<AppToast>(),
));
}
+7 -1
View File
@@ -1,5 +1,5 @@
{
"@@last_modified": "2022-06-13T12:33:59.446625",
"@@last_modified": "2022-06-22T11:25:25.867848",
"initializing_data": "Initializing data...",
"@initializing_data": {
"type": "text",
@@ -1417,5 +1417,11 @@
"type": "text",
"placeholders_order": [],
"placeholders": {}
},
"wrongUrlMessage": "Server URL is not valid, please try again",
"@wrongUrlMessage": {
"type": "text",
"placeholders_order": [],
"placeholders": {}
}
}
@@ -26,6 +26,7 @@ class NetworkBindings extends Bindings {
_bindingDio();
_bindingApi();
_bindingConnection();
_bindingException();
}
void _bindingBaseOption() {
@@ -78,4 +79,8 @@ class NetworkBindings extends Bindings {
void _bindingConnection() {
Get.put(Connectivity());
}
void _bindingException() {
Get.put(RemoteExceptionThrower());
}
}
@@ -1,3 +1,4 @@
import 'package:core/core.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/base_bindings.dart';
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
@@ -11,11 +12,6 @@ import 'package:tmail_ui_user/features/session/domain/usecases/get_session_inter
class SessionBindings extends BaseBindings {
@override
void dependencies() {
super.dependencies();
}
@override
void bindingsController() {
}
@@ -27,7 +23,9 @@ class SessionBindings extends BaseBindings {
@override
void bindingsDataSourceImpl() {
Get.put(SessionDataSourceImpl(Get.find<SessionAPI>()));
Get.put(SessionDataSourceImpl(
Get.find<SessionAPI>(),
Get.find<RemoteExceptionThrower>()));
}
@override
@@ -1448,4 +1448,9 @@ class AppLocalizations {
name: 'noPreviewAvailable',
);
}
String get wrongUrlMessage {
return Intl.message('Server URL is not valid, please try again',
name: 'wrongUrlMessage');
}
}