mirror of
https://github.com/ente-io/ente.git
synced 2025-08-08 15:30:40 +00:00
[auth] Show contact support button on error dialogs
This commit is contained in:
parent
1e83ef0c06
commit
29539d9db2
@ -263,6 +263,8 @@
|
|||||||
"exportLogs": "Export logs",
|
"exportLogs": "Export logs",
|
||||||
"enterYourRecoveryKey": "Enter your recovery key",
|
"enterYourRecoveryKey": "Enter your recovery key",
|
||||||
"tempErrorContactSupportIfPersists": "It looks like something went wrong. Please retry after some time. If the error persists, please contact our support team.",
|
"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.",
|
||||||
"itLooksLikeSomethingWentWrongPleaseRetryAfterSome": "It looks like something went wrong. Please retry after some time. If the error persists, please contact our support team.",
|
"itLooksLikeSomethingWentWrongPleaseRetryAfterSome": "It looks like something went wrong. Please retry after some time. If the error persists, please contact our support team.",
|
||||||
"about": "About",
|
"about": "About",
|
||||||
"weAreOpenSource": "We are open source!",
|
"weAreOpenSource": "We are open source!",
|
||||||
|
@ -49,7 +49,7 @@ class PasskeyService {
|
|||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger('PasskeyService').severe("failed to open passkey page", e);
|
Logger('PasskeyService').severe("failed to open passkey page", e);
|
||||||
showGenericErrorDialog(context: context).ignore();
|
showGenericErrorDialog(context: context, error: e).ignore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ class UserService {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unawaited(showGenericErrorDialog(context: context));
|
unawaited(showGenericErrorDialog(context: context, error: null));
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
await dialog.hide();
|
await dialog.hide();
|
||||||
_logger.info(e);
|
_logger.info(e);
|
||||||
@ -114,12 +114,12 @@ class UserService {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
unawaited(showGenericErrorDialog(context: context));
|
unawaited(showGenericErrorDialog(context: context, error: e));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await dialog.hide();
|
await dialog.hide();
|
||||||
_logger.severe(e);
|
_logger.severe(e);
|
||||||
unawaited(showGenericErrorDialog(context: context));
|
unawaited(showGenericErrorDialog(context: context, error: e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ class UserService {
|
|||||||
//to close and only then to show the error dialog.
|
//to close and only then to show the error dialog.
|
||||||
Future.delayed(
|
Future.delayed(
|
||||||
const Duration(milliseconds: 150),
|
const Duration(milliseconds: 150),
|
||||||
() => showGenericErrorDialog(context: context),
|
() => showGenericErrorDialog(context: context, error: e),
|
||||||
);
|
);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
@ -248,7 +248,10 @@ class UserService {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_logger.severe(e);
|
_logger.severe(e);
|
||||||
await showGenericErrorDialog(context: context);
|
await showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: e,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,7 +412,10 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
|
|||||||
_logger.severe(e, s);
|
_logger.severe(e, s);
|
||||||
await dialog.hide();
|
await dialog.hide();
|
||||||
// ignore: unawaited_futures
|
// ignore: unawaited_futures
|
||||||
showGenericErrorDialog(context: context);
|
showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: e,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,7 +475,10 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
|
|||||||
_logger.severe(e, s);
|
_logger.severe(e, s);
|
||||||
await dialog.hide();
|
await dialog.hide();
|
||||||
// ignore: unawaited_futures
|
// ignore: unawaited_futures
|
||||||
showGenericErrorDialog(context: context);
|
showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: e,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,7 +506,10 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// ignore: unawaited_futures
|
// ignore: unawaited_futures
|
||||||
showGenericErrorDialog(context: context);
|
showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: e,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,10 @@ class _VerifyRecoveryPageState extends State<VerifyRecoveryPage> {
|
|||||||
"Please check your internet connection and try again.",
|
"Please check your internet connection and try again.",
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await showGenericErrorDialog(context: context);
|
await showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: e,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -107,7 +110,10 @@ class _VerifyRecoveryPageState extends State<VerifyRecoveryPage> {
|
|||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore: unawaited_futures
|
// ignore: unawaited_futures
|
||||||
showGenericErrorDialog(context: context);
|
showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: e,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,7 +485,10 @@ class _ButtonChildWidgetState extends State<ButtonChildWidget> {
|
|||||||
} else if (exception != null) {
|
} else if (exception != null) {
|
||||||
//This is to show the execution was unsuccessful if the dialog is manually
|
//This is to show the execution was unsuccessful if the dialog is manually
|
||||||
//closed before the execution completes.
|
//closed before the execution completes.
|
||||||
showGenericErrorDialog(context: context);
|
showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: exception,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ class _HomePageState extends State<HomePage> {
|
|||||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
final TextEditingController _textController = TextEditingController();
|
final TextEditingController _textController = TextEditingController();
|
||||||
final bool _autoFocusSearch = PreferenceService.instance.shouldAutoFocusOnSearchBar();
|
final bool _autoFocusSearch =
|
||||||
|
PreferenceService.instance.shouldAutoFocusOnSearchBar();
|
||||||
bool _showSearchBox = false;
|
bool _showSearchBox = false;
|
||||||
String _searchText = "";
|
String _searchText = "";
|
||||||
List<Code>? _allCodes;
|
List<Code>? _allCodes;
|
||||||
@ -448,7 +449,10 @@ class _HomePageState extends State<HomePage> {
|
|||||||
CodeStore.instance.addCode(newCode);
|
CodeStore.instance.addCode(newCode);
|
||||||
_focusNewCode(newCode);
|
_focusNewCode(newCode);
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
showGenericErrorDialog(context: context);
|
showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: e,
|
||||||
|
);
|
||||||
_logger.severe("error while handling deeplink", e, s);
|
_logger.severe("error while handling deeplink", e, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
|||||||
return;
|
return;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
_logger.severe("failed to check status", e, s);
|
_logger.severe("failed to check status", e, s);
|
||||||
showGenericErrorDialog(context: context).ignore();
|
showGenericErrorDialog(context: context, error: e).ignore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await UserService.instance.onPassKeyVerified(context, response);
|
await UserService.instance.onPassKeyVerified(context, response);
|
||||||
@ -111,7 +111,7 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
|||||||
}
|
}
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
_logger.severe('passKey: failed to handle deeplink', e, s);
|
_logger.severe('passKey: failed to handle deeplink', e, s);
|
||||||
showGenericErrorDialog(context: context).ignore();
|
showGenericErrorDialog(context: context, error: e).ignore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
|||||||
await checkStatus();
|
await checkStatus();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('failed to check status %e');
|
debugPrint('failed to check status %e');
|
||||||
showGenericErrorDialog(context: context).ignore();
|
showGenericErrorDialog(context: context, error: e).ignore();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
shouldSurfaceExecutionStates: true,
|
shouldSurfaceExecutionStates: true,
|
||||||
|
@ -111,7 +111,10 @@ class AccountSectionWidget extends StatelessWidget {
|
|||||||
CryptoUtil.bin2hex(Configuration.instance.getRecoveryKey());
|
CryptoUtil.bin2hex(Configuration.instance.getRecoveryKey());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore: unawaited_futures
|
// ignore: unawaited_futures
|
||||||
showGenericErrorDialog(context: context);
|
showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: e,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ignore: unawaited_futures
|
// ignore: unawaited_futures
|
||||||
|
@ -182,7 +182,10 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
|||||||
PasskeyService.instance.openPasskeyPage(buildContext).ignore();
|
PasskeyService.instance.openPasskeyPage(buildContext).ignore();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
_logger.severe("failed to open passkey page", e, s);
|
_logger.severe("failed to open passkey page", e, s);
|
||||||
await showGenericErrorDialog(context: context);
|
await showGenericErrorDialog(
|
||||||
|
context: context,
|
||||||
|
error: e,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import 'package:ente_auth/ui/components/dialog_widget.dart';
|
|||||||
import 'package:ente_auth/ui/components/models/button_result.dart';
|
import 'package:ente_auth/ui/components/models/button_result.dart';
|
||||||
import 'package:ente_auth/ui/components/models/button_type.dart';
|
import 'package:ente_auth/ui/components/models/button_type.dart';
|
||||||
import 'package:ente_auth/utils/email_util.dart';
|
import 'package:ente_auth/utils/email_util.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
typedef DialogBuilder = DialogWidget Function(BuildContext context);
|
typedef DialogBuilder = DialogWidget Function(BuildContext context);
|
||||||
@ -70,16 +71,77 @@ Future<ButtonResult?> showErrorDialogForException({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String parseErrorForUI(
|
||||||
|
BuildContext context,
|
||||||
|
String genericError, {
|
||||||
|
Object? error,
|
||||||
|
bool surfaceError = kDebugMode,
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
if (error == null) {
|
||||||
|
return genericError;
|
||||||
|
}
|
||||||
|
if (error is DioException) {
|
||||||
|
final DioException dioError = error;
|
||||||
|
if (dioError.type == DioExceptionType.unknown) {
|
||||||
|
if (dioError.error.toString().contains('Failed host lookup')) {
|
||||||
|
return context.l10n.networkHostLookUpErr;
|
||||||
|
} else if (dioError.error.toString().contains('SocketException')) {
|
||||||
|
return context.l10n.networkConnectionRefusedErr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// return generic error if the user is not internal and the error is not in debug mode
|
||||||
|
if (!kDebugMode) {
|
||||||
|
return genericError;
|
||||||
|
}
|
||||||
|
String errorInfo = "";
|
||||||
|
if (error is DioException) {
|
||||||
|
final DioException dioError = error;
|
||||||
|
if (dioError.type == DioExceptionType.badResponse) {
|
||||||
|
if (dioError.response?.data["code"] != null) {
|
||||||
|
errorInfo = "Reason: " + dioError.response!.data["code"];
|
||||||
|
} else {
|
||||||
|
errorInfo = "Reason: " + dioError.response!.data.toString();
|
||||||
|
}
|
||||||
|
} else if (dioError.type == DioExceptionType.unknown) {
|
||||||
|
errorInfo = "Reason: " + dioError.error.toString();
|
||||||
|
} else {
|
||||||
|
errorInfo = "Reason: " + dioError.type.toString();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (kDebugMode) {
|
||||||
|
errorInfo = error.toString();
|
||||||
|
} else {
|
||||||
|
errorInfo = error.toString().split('Source stack')[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errorInfo.isNotEmpty) {
|
||||||
|
return "$genericError\n\n$errorInfo";
|
||||||
|
}
|
||||||
|
return genericError;
|
||||||
|
} catch (e) {
|
||||||
|
return genericError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///Will return null if dismissed by tapping outside
|
///Will return null if dismissed by tapping outside
|
||||||
Future<ButtonResult?> showGenericErrorDialog({
|
Future<ButtonResult?> showGenericErrorDialog({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
bool isDismissible = true,
|
bool isDismissible = true,
|
||||||
|
required Object? error,
|
||||||
}) async {
|
}) async {
|
||||||
|
final errorBody = parseErrorForUI(
|
||||||
|
context,
|
||||||
|
context.l10n.itLooksLikeSomethingWentWrongPleaseRetryAfterSome,
|
||||||
|
error: error,
|
||||||
|
);
|
||||||
|
|
||||||
return showDialogWidget(
|
return showDialogWidget(
|
||||||
context: context,
|
context: context,
|
||||||
title: context.l10n.error,
|
title: context.l10n.error,
|
||||||
icon: Icons.error_outline_outlined,
|
icon: Icons.error_outline_outlined,
|
||||||
body: context.l10n.itLooksLikeSomethingWentWrongPleaseRetryAfterSome,
|
body: errorBody,
|
||||||
isDismissible: isDismissible,
|
isDismissible: isDismissible,
|
||||||
buttons: [
|
buttons: [
|
||||||
ButtonWidget(
|
ButtonWidget(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user