diff --git a/lib/anypay/anypay_api.dart b/lib/anypay/anypay_api.dart index 679d0eabf..8af3be08c 100644 --- a/lib/anypay/anypay_api.dart +++ b/lib/anypay/anypay_api.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart'; +import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart'; import 'package:cw_core/crypto_currency.dart'; @@ -55,6 +56,7 @@ class AnyPayApi { final response = await post(url, headers: headers, body: utf8.encode(json.encode(body))); if (response.statusCode != 200) { + ExceptionHandler.onError(FlutterErrorDetails(exception: response)); throw Exception('Unexpected response http code: ${response.statusCode}'); } diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart index cd563dc1a..002534ea1 100644 --- a/lib/utils/exception_handler.dart +++ b/lib/utils/exception_handler.dart @@ -136,9 +136,11 @@ class ExceptionHandler { "errno = 54", // SocketException: Connection reset by peer "errno = 57", // SocketException: Read failed (OS Error: Socket is not connected) "errno = 60", // SocketException: Operation timed out + "errno = 65", // SocketException: No route to host "errno = 103", // SocketException: Software caused connection abort "errno = 104", // SocketException: Connection reset by peer "errno = 110", // SocketException: Connection timed out + "HttpException: Connection reset by peer", "HttpException: Connection closed before full header was received", "HandshakeException: Connection terminated during handshake", "PERMISSION_NOT_GRANTED", diff --git a/lib/utils/share_util.dart b/lib/utils/share_util.dart index 701fcea1d..cfb9e74ab 100644 --- a/lib/utils/share_util.dart +++ b/lib/utils/share_util.dart @@ -28,7 +28,11 @@ class ShareUtil { ); } - static Rect? _sharePosition(BuildContext context) { + static Rect _sharePosition(BuildContext context) { + if (!context.mounted) { + return Rect.zero; + } + final box = context.findRenderObject() as RenderBox?; return box!.localToGlobal(Offset.zero) & box.size; diff --git a/lib/view_model/order_details_view_model.dart b/lib/view_model/order_details_view_model.dart index 77284ab6d..0047ed7b2 100644 --- a/lib/view_model/order_details_view_model.dart +++ b/lib/view_model/order_details_view_model.dart @@ -81,21 +81,23 @@ abstract class OrderDetailsViewModelBase with Store { : S.current.trade_details_fetching), ]); - if (order.provider != null) { - items.add( - StandartListItem( - title: 'Buy provider', - value: order.provider.title) - ); - } + items.add( + StandartListItem( + title: 'Buy provider', + value: order.provider.title) + ); - if (_provider!.trackUrl?.isNotEmpty ?? false) { + if (_provider?.trackUrl.isNotEmpty ?? false) { final buildURL = _provider!.trackUrl + '${order.transferId}'; items.add( TrackTradeListItem( title: 'Track', value: buildURL, - onTap: () => launch(buildURL) + onTap: () { + try { + launch(buildURL); + } catch (e) {} + } ) ); } diff --git a/lib/view_model/trade_details_view_model.dart b/lib/view_model/trade_details_view_model.dart index 3a6f1ec74..e32e36887 100644 --- a/lib/view_model/trade_details_view_model.dart +++ b/lib/view_model/trade_details_view_model.dart @@ -21,6 +21,7 @@ import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart import 'package:cake_wallet/src/screens/trade_details/trade_details_list_card.dart'; import 'package:cake_wallet/src/screens/trade_details/trade_details_status_item.dart'; import 'package:url_launcher/url_launcher.dart'; + part 'trade_details_view_model.g.dart'; class TradeDetailsViewModel = TradeDetailsViewModelBase with _$TradeDetailsViewModel; @@ -121,23 +122,26 @@ abstract class TradeDetailsViewModelBase with Store { title: 'Track', value: buildURL, onTap: () { - launch(buildURL); + _launchUrl(buildURL); })); } if (trade.provider == ExchangeProviderDescription.sideShift) { final buildURL = 'https://sideshift.ai/orders/${trade.id.toString()}'; - items.add(TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => launch(buildURL))); + items.add( + TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => _launchUrl(buildURL))); } if (trade.provider == ExchangeProviderDescription.simpleSwap) { final buildURL = 'https://simpleswap.io/exchange?id=${trade.id.toString()}'; - items.add(TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => launch(buildURL))); + items.add( + TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => _launchUrl(buildURL))); } if (trade.provider == ExchangeProviderDescription.trocador) { final buildURL = 'https://trocador.app/en/checkout/${trade.id.toString()}'; - items.add(TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => launch(buildURL))); + items.add( + TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => _launchUrl(buildURL))); items.add(StandartListItem( title: '${trade.providerName} ${S.current.id.toUpperCase()}', @@ -148,4 +152,10 @@ abstract class TradeDetailsViewModelBase with Store { title: '${trade.providerName} ${S.current.password}', value: trade.password ?? '')); } } + + void _launchUrl(String url) { + try { + launch(url); + } catch (e) {} + } } diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart index f8729715b..a37a6fa2f 100644 --- a/lib/view_model/transaction_details_view_model.dart +++ b/lib/view_model/transaction_details_view_model.dart @@ -14,7 +14,6 @@ import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:cake_wallet/monero/monero.dart'; -import 'package:cake_wallet/haven/haven.dart'; part 'transaction_details_view_model.g.dart'; @@ -150,7 +149,11 @@ abstract class TransactionDetailsViewModelBase with Store { items.add(BlockExplorerListItem( title: S.current.view_in_block_explorer, value: _explorerDescription(type), - onTap: () => launch(_explorerUrl(type, tx.id)))); + onTap: () { + try { + launch(_explorerUrl(type, tx.id)); + } catch (e) {} + })); final description = transactionDescriptionBox.values.firstWhere( (val) => val.id == transactionInfo.id,