Surface network error on UI + show contact support in generic err dialog (#1548)

This commit is contained in:
Neeraj Gupta 2023-11-30 10:53:42 +05:30 committed by GitHub
commit 8e8ac25a66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 212 additions and 85 deletions

View file

@ -64,3 +64,5 @@ const defaultRadiusValue = 40.0;
const galleryGridSpacing = 2.0;
const searchSectionLimit = 7;
bool isInternalUser = false;

View file

@ -869,6 +869,10 @@ class MessageLookup extends MessageLookupByLibrary {
"movingFilesToAlbum":
MessageLookupByLibrary.simpleMessage("Moving files to album..."),
"name": MessageLookupByLibrary.simpleMessage("Name"),
"networkConnectionRefusedErr": MessageLookupByLibrary.simpleMessage(
"Unable to connect to Ente, please retry after sometime. If the error persists, please contact support."),
"networkHostLookUpErr": MessageLookupByLibrary.simpleMessage(
"Unable to connect to Ente, please check your network settings and contact support if the error persists."),
"never": MessageLookupByLibrary.simpleMessage("Never"),
"newAlbum": MessageLookupByLibrary.simpleMessage("New album"),
"newToEnte": MessageLookupByLibrary.simpleMessage("New to ente"),

View file

@ -6529,6 +6529,26 @@ class S {
);
}
/// `Unable to connect to Ente, please check your network settings and contact support if the error persists.`
String get networkHostLookUpErr {
return Intl.message(
'Unable to connect to Ente, please check your network settings and contact support if the error persists.',
name: 'networkHostLookUpErr',
desc: '',
args: [],
);
}
/// `Unable to connect to Ente, please retry after sometime. If the error persists, please contact support.`
String get networkConnectionRefusedErr {
return Intl.message(
'Unable to connect to Ente, please retry after sometime. If the error persists, please contact support.',
name: 'networkConnectionRefusedErr',
desc: '',
args: [],
);
}
/// `Cached data`
String get cachedData {
return Intl.message(

View file

@ -929,6 +929,8 @@
"itLooksLikeSomethingWentWrongPleaseRetryAfterSome": "It looks like something went wrong. Please retry after some time. If the error persists, please contact our support team.",
"error": "Error",
"tempErrorContactSupportIfPersists": "It looks like something went wrong. Please retry after some time. If the error persists, please contact our support team.",
"networkHostLookUpErr" : "Unable to connect to Ente, please check your network settings and contact support if the error persists.",
"networkConnectionRefusedErr" : "Unable to connect to Ente, please retry after sometime. If the error persists, please contact support.",
"cachedData": "Cached data",
"clearCaches": "Clear caches",
"remoteImages": "Remote images",

View file

@ -222,7 +222,7 @@ extension SectionTypeExtensions on SectionType {
},
);
if (result is Exception) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: result);
}
};
default:

View file

@ -196,7 +196,7 @@ class BillingService {
);
} catch (e) {
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
await dialog.hide();
}

View file

@ -71,9 +71,10 @@ class FeatureFlagService {
bool isInternalUserOrDebugBuild() {
final String? email = Configuration.instance.getEmail();
final userID = Configuration.instance.getUserID();
return (email != null && email.endsWith("@ente.io")) ||
isInternalUser = (email != null && email.endsWith("@ente.io")) ||
_internalUserIDs.contains(userID) ||
kDebugMode;
return isInternalUser;
}
Future<void> fetchFeatureFlags() async {

View file

@ -154,7 +154,7 @@ extension HiddenService on CollectionsService {
} catch (e, s) {
_logger.severe("Could not hide", e, s);
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return false;
} finally {
await dialog.hide();

View file

@ -113,8 +113,9 @@ class UserService {
),
);
return;
} else {
throw Exception("send-ott action failed, non-200");
}
unawaited(showGenericErrorDialog(context: context));
} on DioError catch (e) {
await dialog.hide();
_logger.info(e);
@ -127,12 +128,14 @@ class UserService {
),
);
} else {
unawaited(showGenericErrorDialog(context: context));
unawaited(showGenericErrorDialog(context: context, error: e));
}
} catch (e) {
} catch (e, s) {
await dialog.hide();
_logger.severe(e);
unawaited(showGenericErrorDialog(context: context));
_logger.severe(e, s);
unawaited(
showGenericErrorDialog(context: context, error: e),
);
}
}
@ -259,7 +262,7 @@ class UserService {
//to close and only then to show the error dialog.
Future.delayed(
const Duration(milliseconds: 150),
() => showGenericErrorDialog(context: context),
() => showGenericErrorDialog(context: context, error: null),
);
}
}
@ -279,7 +282,7 @@ class UserService {
}
} catch (e) {
_logger.severe(e);
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(context: context, error: e);
return null;
}
}
@ -956,7 +959,7 @@ class UserService {
try {
recoveryKey = await getOrCreateRecoveryKey(context);
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return false;
}
final dialog = createProgressDialog(context, S.of(context).verifying);

View file

@ -262,7 +262,7 @@ class _DeleteAccountPageState extends State<DeleteAccountPage> {
isDismissible: false,
);
if (choice!.action == ButtonAction.error) {
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(context: context, error: choice.exception);
}
}
@ -289,7 +289,7 @@ class _DeleteAccountPageState extends State<DeleteAccountPage> {
showShortToast(context, S.of(context).yourAccountHasBeenDeleted);
} catch (e, s) {
Logger("DeleteAccount").severe("failed to delete", e, s);
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
}

View file

@ -404,7 +404,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
} catch (e, s) {
_logger.severe(e, s);
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
}
@ -456,7 +456,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
} catch (e, s) {
_logger.severe(e, s);
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
}
@ -481,7 +481,7 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
S.of(context).sorryWeCouldNotGenerateSecureKeysOnThisDevicennplease,
);
} else {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
}
}

View file

@ -51,7 +51,7 @@ class _VerifyRecoveryPageState extends State<VerifyRecoveryPage> {
"Please check your internet connection and try again.",
);
} else {
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(context: context, error: e);
}
return;
}
@ -109,7 +109,7 @@ class _VerifyRecoveryPageState extends State<VerifyRecoveryPage> {
),
);
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return;
}
}

View file

@ -73,7 +73,7 @@ extension CollectionFileActions on CollectionActions {
);
if (actionResult?.action != null &&
actionResult!.action == ButtonAction.error) {
showGenericErrorDialog(context: bContext);
showGenericErrorDialog(context: bContext, error: actionResult.exception);
} else {
selectedFiles.clearAll();
}
@ -187,7 +187,7 @@ extension CollectionFileActions on CollectionActions {
} catch (e, s) {
logger.severe("Failed to add to album", e, s);
await dialog?.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
rethrow;
}
}

View file

@ -52,7 +52,7 @@ class CollectionActions {
_showUnSupportedAlert(context);
} else {
logger.severe("Failed to update shareUrl collection", e);
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
return false;
}
@ -93,7 +93,7 @@ class CollectionActions {
);
if (actionResult?.action != null) {
if (actionResult!.action == ButtonAction.error) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: actionResult.exception);
}
return actionResult.action == ButtonAction.first;
} else {
@ -142,7 +142,7 @@ class CollectionActions {
return collection;
} catch (e, s) {
dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
logger.severe("Failing to create link for selected files", e, s);
}
return null;
@ -183,7 +183,7 @@ class CollectionActions {
);
if (actionResult?.action != null) {
if (actionResult!.action == ButtonAction.error) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: actionResult.exception);
}
return actionResult.action == ButtonAction.first;
}
@ -230,7 +230,7 @@ class CollectionActions {
} catch (e) {
await dialog?.hide();
logger.severe("Failed to get public key", e);
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return false;
}
// getPublicKey can return null when no user is associated with given
@ -272,7 +272,7 @@ class CollectionActions {
_showUnSupportedAlert(context);
} else {
logger.severe("failed to share collection", e);
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
return false;
}
@ -353,7 +353,7 @@ class CollectionActions {
);
if (actionResult?.action != null &&
actionResult!.action == ButtonAction.error) {
showGenericErrorDialog(context: bContext);
showGenericErrorDialog(context: bContext, error: actionResult.exception);
return false;
}
if ((actionResult?.action != null) &&

View file

@ -125,7 +125,7 @@ Future<void> showSingleFileDeleteSheet(
);
if (actionResult?.action != null &&
actionResult!.action == ButtonAction.error) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: actionResult.exception);
}
}

View file

@ -111,6 +111,7 @@ class AlbumVerticalListWidget extends StatelessWidget {
if (result is Exception) {
showGenericErrorDialog(
context: context,
error: result,
);
_logger.severe(
"Failed to name album",
@ -310,7 +311,7 @@ class AlbumVerticalListWidget extends StatelessWidget {
);
return true;
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return false;
}
}
@ -333,7 +334,7 @@ class AlbumVerticalListWidget extends StatelessWidget {
),
);
} else {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: result);
_logger.severe("Cannot share collections owned by others");
}
}
@ -352,7 +353,10 @@ class AlbumVerticalListWidget extends StatelessWidget {
),
);
} else {
showGenericErrorDialog(context: context);
showGenericErrorDialog(
context: context,
error: Exception("Can not share collection owned by others"),
);
_logger.severe("Cannot share collections owned by others");
}
return Future.value(true);
@ -409,7 +413,7 @@ class AlbumVerticalListWidget extends StatelessWidget {
} catch (e, s) {
_logger.severe("Could not move to album", e, s);
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return false;
}
}
@ -438,7 +442,7 @@ class AlbumVerticalListWidget extends StatelessWidget {
} catch (e, s) {
_logger.severe("Could not move to album", e, s);
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return false;
}
}

View file

@ -55,7 +55,7 @@ class NewAlbumIcon extends StatelessWidget {
},
);
if (result is Exception) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: result);
}
},
);

View file

@ -498,7 +498,7 @@ class _ButtonChildWidgetState extends State<ButtonChildWidget> {
} else if (exception != null) {
//This is to show the execution was unsuccessful if the dialog is manually
//closed before the execution completes.
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: exception);
}
}
}

View file

@ -36,7 +36,7 @@ class _FullScreenMemoryState extends State<FullScreenMemory> {
bool _showCounter = false;
bool _showStepIndicator = true;
PageController? _pageController;
bool _shouldDisableScroll = false;
final bool _shouldDisableScroll = false;
late int currentUserID;
final GlobalKey shareButtonKey = GlobalKey();

View file

@ -123,7 +123,7 @@ class ChildSubscriptionWidget extends StatelessWidget {
},
);
if (choice!.action == ButtonAction.error) {
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(context: context, error: choice.exception);
}
}
}

View file

@ -190,7 +190,10 @@ class _PaymentWebPageState extends State<PaymentWebPage> {
} else {
// should never reach here
_logger.severe("unexpected status", uri.toString());
showGenericErrorDialog(context: context);
showGenericErrorDialog(
context: context,
error: Exception("expected payment status $paymentStatus"),
);
}
}

View file

@ -524,11 +524,14 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
final ProductDetailsResponse response =
await InAppPurchase.instance.queryProductDetails({productID});
if (response.notFoundIDs.isNotEmpty) {
_logger.severe(
"Could not find products: " + response.notFoundIDs.toString(),
);
final errMsg = "Could not find products: " +
response.notFoundIDs.toString();
_logger.severe(errMsg);
await _dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(
context: context,
error: Exception(errMsg),
);
return;
}
final isCrossGradingOnAndroid = Platform.isAndroid &&

View file

@ -337,7 +337,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
).then((value) => onWebPaymentGoBack);
} catch (e) {
await _dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
await _dialog.hide();
}

View file

@ -232,7 +232,7 @@ class _BackupFolderSelectionPageState extends State<BackupFolderSelectionPage> {
} catch (e, s) {
_logger.severe("Failed to updated backup folder", e, s);
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
}

View file

@ -94,7 +94,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
try {
status = await SyncService.instance.getBackupStatus();
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return;
}
@ -128,7 +128,7 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
duplicates =
await DeduplicationService.instance.getDuplicateFiles();
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return;
}

View file

@ -89,7 +89,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
try {
recoveryKey = await _getOrCreateRecoveryKey(context);
} catch (e) {
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(context: context, error: e);
return;
}
unawaited(
@ -260,14 +260,22 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
await UserService.instance.getOrCreateRecoveryKey(context),
);
}
Future<void> updateEmailMFA(bool isEnabled) async {
try {
final UserDetails details = await UserService.instance.getUserDetailsV2(memoryCount: false);
if((details.profileData?.canDisableEmailMFA ?? false) == false) {
await routeToPage(context, RequestPasswordVerificationPage(onPasswordVerified: (Uint8List keyEncryptionKey) async {
final Uint8List loginKey = await CryptoUtil.deriveLoginKey(keyEncryptionKey);
await UserService.instance.registerOrUpdateSrp(loginKey);
},),);
final UserDetails details =
await UserService.instance.getUserDetailsV2(memoryCount: false);
if ((details.profileData?.canDisableEmailMFA ?? false) == false) {
await routeToPage(
context,
RequestPasswordVerificationPage(
onPasswordVerified: (Uint8List keyEncryptionKey) async {
final Uint8List loginKey =
await CryptoUtil.deriveLoginKey(keyEncryptionKey);
await UserService.instance.registerOrUpdateSrp(loginKey);
},
),
);
}
await UserService.instance.updateEmailMFA(isEnabled);
} catch (e) {

View file

@ -132,7 +132,7 @@ class _ManageIndividualParticipantState
CollectionParticipantRole.viewer,
);
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
if (isConvertToViewSuccess && mounted) {
// reset value

View file

@ -347,7 +347,7 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
}
} catch (e) {
await dialog?.hide();
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(context: context, error: e);
rethrow;
}
}

View file

@ -137,7 +137,7 @@ class _ItemsWidgetState extends State<ItemsWidget> {
try {
await CollectionsService.instance.updateShareUrl(widget.collection, prop);
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
rethrow;
}
}

View file

@ -180,7 +180,7 @@ class _ItemsWidgetState extends State<ItemsWidget> {
try {
await CollectionsService.instance.updateShareUrl(widget.collection, prop);
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
rethrow;
}
}

View file

@ -288,7 +288,7 @@ class FileAppBarState extends State<FileAppBar> {
}
} catch (e, s) {
_logger.severe("failed to update file visibility", e, s);
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(context: context, error: e);
}
}
@ -371,7 +371,7 @@ class FileAppBarState extends State<FileAppBar> {
} catch (e) {
_logger.warning("Failed to save file", e);
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
} finally {
PhotoManager.startChangeNotify();
LocalSyncService.instance.checkAndSync().ignore();
@ -432,7 +432,7 @@ class FileAppBarState extends State<FileAppBar> {
} catch (e) {
dialog.hide();
_logger.severe("Failed to use as", e);
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
}
}

View file

@ -31,7 +31,7 @@ class EmptyAlbumState extends StatelessWidget {
try {
await showAddPhotosSheet(context, c);
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
},
),

View file

@ -172,7 +172,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
},
);
if (result is Exception) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: result);
}
}
@ -204,7 +204,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
);
if (actionResult?.action != null && mounted) {
if (actionResult!.action == ButtonAction.error) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: actionResult.exception);
} else if (actionResult.action == ButtonAction.first) {
Navigator.of(context).pop();
}
@ -224,7 +224,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
.getBackupStatus(pathID: widget.deviceCollection!.id);
} catch (e) {
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
return;
}
@ -664,7 +664,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
} catch (e, s) {
_logger.severe("failed to trash collection", e, s);
await dialog.hide();
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
} else {
final bool result = await collectionActions.deleteCollectionSheet(
@ -691,7 +691,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
}
} catch (e, s) {
_logger.severe("failed to trash collection", e, s);
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
}
@ -726,7 +726,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
}
} catch (e, s) {
_logger.severe(e, s);
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
}
@ -736,7 +736,7 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
await showAddPhotosSheet(bContext, collection!);
} catch (e, s) {
_logger.severe(e, s);
showGenericErrorDialog(context: bContext);
showGenericErrorDialog(context: bContext, error: e);
}
}

View file

@ -118,7 +118,7 @@ class LocationScreenPopUpMenu extends StatelessWidget {
);
Navigator.of(context).pop();
} catch (e) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
}
}
},

View file

@ -200,7 +200,7 @@ class _RadiusPickerWidgetState extends State<RadiusPickerWidget> {
alignMessage: Alignment.centerRight,
);
if (result is Exception) {
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(context: context, error: result);
_logger.severe(
"Failed to create custom radius",
result,

View file

@ -102,7 +102,7 @@ Future<void> deleteFilesFromEverywhere(
await FilesDB.instance.deleteMultipleUploadedFiles(fileIDs);
} catch (e) {
_logger.severe(e);
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
rethrow;
}
for (final collectionID in updatedCollectionIDs) {
@ -163,7 +163,7 @@ Future<void> deleteFilesFromRemoteOnly(
await FilesDB.instance.deleteMultipleUploadedFiles(uploadedFileIDs);
} catch (e, s) {
_logger.severe("Failed to delete files from remote", e, s);
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
rethrow;
}
for (final collectionID in updatedCollectionIDs) {
@ -279,7 +279,10 @@ Future<bool> deleteFromTrash(BuildContext context, List<EnteFile> files) async {
actionResult!.action == ButtonAction.cancel) {
return didDeletionStart ? true : false;
} else if (actionResult.action == ButtonAction.error) {
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(
context: context,
error: actionResult.exception,
);
return false;
} else {
return true;
@ -306,7 +309,10 @@ Future<bool> emptyTrash(BuildContext context) async {
actionResult!.action == ButtonAction.cancel) {
return false;
} else if (actionResult.action == ButtonAction.error) {
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(
context: context,
error: actionResult.exception,
);
return false;
} else {
return true;
@ -555,7 +561,7 @@ Future<void> showDeleteSheet(
showShortToast(context, S.of(context).movedToTrash);
},
onError: (e, s) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: e);
},
);
},
@ -620,7 +626,7 @@ Future<void> showDeleteSheet(
);
if (actionResult?.action != null &&
actionResult!.action == ButtonAction.error) {
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: actionResult.exception);
} else {
selectedFiles.clearAll();
}

View file

@ -1,6 +1,8 @@
import "package:dio/dio.dart";
import "package:flutter/foundation.dart";
import 'package:flutter/material.dart';
import "package:flutter/services.dart";
import "package:photos/core/constants.dart";
import "package:photos/generated/l10n.dart";
import 'package:photos/models/button_result.dart';
import 'package:photos/models/typedefs.dart';
@ -11,6 +13,7 @@ import 'package:photos/ui/components/action_sheet_widget.dart';
import 'package:photos/ui/components/buttons/button_widget.dart';
import 'package:photos/ui/components/dialog_widget.dart';
import 'package:photos/ui/components/models/button_type.dart';
import "package:photos/utils/email_util.dart";
typedef DialogBuilder = DialogWidget Function(BuildContext context);
@ -68,25 +71,93 @@ Future<ButtonResult?> showErrorDialogForException({
);
}
String parseErrorForUI(
BuildContext context,
String genericError, {
Object? error,
bool surfaceError = kDebugMode,
}) {
if (error == null) {
return genericError;
}
if (error is DioError) {
final DioError dioError = error;
if (dioError.type == DioErrorType.other) {
if (dioError.error.toString().contains('Failed host lookup')) {
return S.of(context).networkHostLookUpErr;
} else if (dioError.error.toString().contains('SocketException')) {
return S.of(context).networkConnectionRefusedErr;
}
}
}
// return generic error if the user is not internal and the error is not in debug mode
if (!(isInternalUser && kDebugMode)) {
return genericError;
}
String errorInfo = "";
if (error is DioError) {
final DioError dioError = error;
if (dioError.type == DioErrorType.response) {
if (dioError.response?.data["code"] != null) {
errorInfo = "Reason: " + dioError.response!.data["code"];
} else {
errorInfo = "Reason: " + dioError.response!.data.toString();
}
} else if (dioError.type == DioErrorType.other) {
errorInfo = "Reason: " + dioError.error.toString();
} else {
errorInfo = "Reason: " + dioError.type.toString();
}
} else {
errorInfo = error.toString().split('Source stack')[0];
}
if (errorInfo.isNotEmpty) {
return "$genericError\n\n$errorInfo";
}
return genericError;
}
///Will return null if dismissed by tapping outside
Future<ButtonResult?> showGenericErrorDialog({
required BuildContext context,
bool isDismissible = true,
required Object? error,
}) async {
return showDialogWidget(
final errorBody = parseErrorForUI(
context,
S.of(context).itLooksLikeSomethingWentWrongPleaseRetryAfterSome,
error: error,
);
final ButtonResult? result = await showDialogWidget(
context: context,
title: S.of(context).error,
icon: Icons.error_outline_outlined,
body: S.of(context).itLooksLikeSomethingWentWrongPleaseRetryAfterSome,
body: errorBody,
isDismissible: isDismissible,
buttons: const [
buttons: [
ButtonWidget(
buttonType: ButtonType.primary,
labelText: S.of(context).ok,
buttonAction: ButtonAction.first,
isInAlert: true,
),
ButtonWidget(
buttonType: ButtonType.secondary,
labelText: "OK",
isInAlert: true,
labelText: S.of(context).contactSupport,
buttonAction: ButtonAction.second,
onTap: () async {
await sendLogs(
context,
S.of(context).contactSupport,
"support@ente.io",
postShare: () {},
);
},
),
],
);
return result;
}
DialogWidget choiceDialog({

View file

@ -218,7 +218,7 @@ Future<void> editFilename(
);
if (result is Exception) {
_logger.severe("Failed to rename file");
showGenericErrorDialog(context: context);
showGenericErrorDialog(context: context, error: result);
}
}

View file

@ -74,7 +74,7 @@ Future<void> share(
s,
);
await dialog.hide();
await showGenericErrorDialog(context: context);
await showGenericErrorDialog(context: context, error: e);
}
}

View file

@ -12,7 +12,7 @@ description: ente photos application
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.8.4+524
version: 0.8.5+525
environment:
sdk: ">=3.0.0 <4.0.0"