V4.6.1 report fixes (#859)
* Add exception handler to anypay api response failure * Check if context is still mounted before fetching iPad position * Add user connection issue to ignored errors * Wrap launchURL in empty try catch to avoid package un-needed exceptions
Omar Hatem committed
Mar 31, 2023 at 21:14 UTC
37ef63d09e5f530b8c598fbd26e350344a179c70
6 files changed
+39
-16
lib/anypay/anypay_api.dart
+2
@@ -1,5 +1,6 @@
1
import 'dart:convert';
2
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
3
+import 'package:cake_wallet/utils/exception_handler.dart';
4
import 'package:flutter/foundation.dart';
5
import 'package:http/http.dart';
6
import 'package:cw_core/crypto_currency.dart';
@@ -55,6 +56,7 @@ class AnyPayApi {
56
final response = await post(url, headers: headers, body: utf8.encode(json.encode(body)));
57
58
if (response.statusCode != 200) {
59
+ ExceptionHandler.onError(FlutterErrorDetails(exception: response));
60
throw Exception('Unexpected response http code: ${response.statusCode}');
61
}
62
lib/utils/exception_handler.dart
+2
@@ -136,9 +136,11 @@ class ExceptionHandler {
136
"errno = 54", // SocketException: Connection reset by peer
137
"errno = 57", // SocketException: Read failed (OS Error: Socket is not connected)
138
"errno = 60", // SocketException: Operation timed out
139
+ "errno = 65", // SocketException: No route to host
140
"errno = 103", // SocketException: Software caused connection abort
141
"errno = 104", // SocketException: Connection reset by peer
142
"errno = 110", // SocketException: Connection timed out
143
+ "HttpException: Connection reset by peer",
144
"HttpException: Connection closed before full header was received",
145
"HandshakeException: Connection terminated during handshake",
146
"PERMISSION_NOT_GRANTED",
lib/utils/share_util.dart
+5
-1
@@ -28,7 +28,11 @@ class ShareUtil {
28
);
29
}
30
31
- static Rect? _sharePosition(BuildContext context) {
31
+ static Rect _sharePosition(BuildContext context) {
32
+ if (!context.mounted) {
33
+ return Rect.zero;
34
+ }
35
+
36
final box = context.findRenderObject() as RenderBox?;
37
38
return box!.localToGlobal(Offset.zero) & box.size;
lib/view_model/order_details_view_model.dart
+11
-9
@@ -81,21 +81,23 @@ abstract class OrderDetailsViewModelBase with Store {
81
: S.current.trade_details_fetching),
82
]);
83
84
- if (order.provider != null) {
85
- items.add(
86
- StandartListItem(
87
- title: 'Buy provider',
88
- value: order.provider.title)
89
- );
90
- }
84
+ items.add(
85
+ StandartListItem(
86
+ title: 'Buy provider',
87
+ value: order.provider.title)
88
+ );
89
92
- if (_provider!.trackUrl?.isNotEmpty ?? false) {
90
+ if (_provider?.trackUrl.isNotEmpty ?? false) {
91
final buildURL = _provider!.trackUrl + '${order.transferId}';
92
items.add(
93
TrackTradeListItem(
94
title: 'Track',
95
value: buildURL,
98
- onTap: () => launch(buildURL)
96
+ onTap: () {
97
+ try {
98
+ launch(buildURL);
99
+ } catch (e) {}
100
+ }
101
)
102
);
103
}
lib/view_model/trade_details_view_model.dart
+14
-4
@@ -21,6 +21,7 @@ import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart
21
import 'package:cake_wallet/src/screens/trade_details/trade_details_list_card.dart';
22
import 'package:cake_wallet/src/screens/trade_details/trade_details_status_item.dart';
23
import 'package:url_launcher/url_launcher.dart';
24
+
25
part 'trade_details_view_model.g.dart';
26
27
class TradeDetailsViewModel = TradeDetailsViewModelBase with _$TradeDetailsViewModel;
@@ -121,23 +122,26 @@ abstract class TradeDetailsViewModelBase with Store {
122
title: 'Track',
123
value: buildURL,
124
onTap: () {
124
- launch(buildURL);
125
+ _launchUrl(buildURL);
126
}));
127
}
128
129
if (trade.provider == ExchangeProviderDescription.sideShift) {
130
final buildURL = 'https://sideshift.ai/orders/${trade.id.toString()}';
130
- items.add(TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => launch(buildURL)));
131
+ items.add(
132
+ TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => _launchUrl(buildURL)));
133
}
134
135
if (trade.provider == ExchangeProviderDescription.simpleSwap) {
136
final buildURL = 'https://simpleswap.io/exchange?id=${trade.id.toString()}';
135
- items.add(TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => launch(buildURL)));
137
+ items.add(
138
+ TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => _launchUrl(buildURL)));
139
}
140
141
if (trade.provider == ExchangeProviderDescription.trocador) {
142
final buildURL = 'https://trocador.app/en/checkout/${trade.id.toString()}';
140
- items.add(TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => launch(buildURL)));
143
+ items.add(
144
+ TrackTradeListItem(title: 'Track', value: buildURL, onTap: () => _launchUrl(buildURL)));
145
146
items.add(StandartListItem(
147
title: '${trade.providerName} ${S.current.id.toUpperCase()}',
@@ -148,4 +152,10 @@ abstract class TradeDetailsViewModelBase with Store {
152
title: '${trade.providerName} ${S.current.password}', value: trade.password ?? ''));
153
}
154
}
155
+
156
+ void _launchUrl(String url) {
157
+ try {
158
+ launch(url);
159
+ } catch (e) {}
160
+ }
161
}
lib/view_model/transaction_details_view_model.dart
+5
-2
@@ -14,7 +14,6 @@ import 'package:cake_wallet/store/settings_store.dart';
14
import 'package:cake_wallet/generated/i18n.dart';
15
import 'package:url_launcher/url_launcher.dart';
16
import 'package:cake_wallet/monero/monero.dart';
17
-import 'package:cake_wallet/haven/haven.dart';
17
18
part 'transaction_details_view_model.g.dart';
19
@@ -150,7 +149,11 @@ abstract class TransactionDetailsViewModelBase with Store {
149
items.add(BlockExplorerListItem(
150
title: S.current.view_in_block_explorer,
151
value: _explorerDescription(type),
153
- onTap: () => launch(_explorerUrl(type, tx.id))));
152
+ onTap: () {
153
+ try {
154
+ launch(_explorerUrl(type, tx.id));
155
+ } catch (e) {}
156
+ }));
157
158
final description = transactionDescriptionBox.values.firstWhere(
159
(val) => val.id == transactionInfo.id,