Skip to content

Commit 7edf858

Browse files
committed
Updated error handling
-If no internet, the error will indicate no internet instead of stale data -If no internet, you can't add new addresses or exchange apis -fixed issue where exchange balances would stop updating once an error happened -fixed issue where explorers weren't updating errors properly
1 parent 34a2b53 commit 7edf858

File tree

15 files changed

+172
-60
lines changed

15 files changed

+172
-60
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ android {
2323
applicationId "com.nebulights.coinstacks"
2424
minSdkVersion 21
2525
targetSdkVersion 26
26-
versionCode 11
27-
versionName "2.0.1"
26+
versionCode 12
27+
versionName "2.0.2"
2828
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
2929
}
3030
buildTypes {

app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
xmlns:tools="http://schemas.android.com/tools"
44
package="com.nebulights.coinstacks">
55

6+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
7+
68
<application
79
android:name="com.nebulights.coinstacks.MyApplication"
810
android:allowBackup="true"
911
android:icon="@mipmap/ic_launcher"
1012
tools:replace="android:label"
11-
android:label="@string/app_name"
13+
android:label="coinstacks"
1214
android:supportsRtl="true"
1315
android:theme="@style/AppTheme">
1416
<activity android:name="com.nebulights.coinstacks.Portfolio.Main.PortfolioActivity">
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.nebulights.coinstacks.Common
2+
3+
import android.content.Context
4+
import android.net.ConnectivityManager
5+
import com.nebulights.coinstacks.R
6+
7+
class ConnectionChecker(val context: Context) {
8+
9+
var noInternetMessage: String = context.getString(R.string.no_internet_connection)
10+
11+
fun isInternetAvailable(): Boolean {
12+
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
13+
val networkInfo = connectivityManager.activeNetworkInfo
14+
return networkInfo?.isConnected ?: false
15+
}
16+
}

app/src/main/java/com/nebulights/coinstacks/Network/BlockExplorers/BaseExplorer.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.nebulights.coinstacks.Network.exchanges.NetworkCompletionCallback
77
import io.reactivex.Observable
88
import io.reactivex.android.schedulers.AndroidSchedulers
99
import io.reactivex.disposables.CompositeDisposable
10+
import io.reactivex.rxkotlin.addTo
1011
import io.reactivex.schedulers.Schedulers
1112
import java.math.BigDecimal
1213
import java.math.RoundingMode
@@ -29,7 +30,6 @@ abstract class BaseExplorer : Explorer {
2930
fun <T> startFeed(observable: Observable<T>, watchAddress: WatchAddress, presenterCallback: NetworkCompletionCallback, explorerNetworkDataUpdate: ExplorerNetworkDataUpdate) {
3031
val disposable = observable.observeOn(AndroidSchedulers.mainThread())
3132
.repeatWhen { result -> result.delay(60, TimeUnit.SECONDS) }
32-
.retryWhen { error -> error.delay(60, TimeUnit.SECONDS) }
3333
.subscribeOn(Schedulers.io())
3434
.subscribe({ result ->
3535

@@ -51,6 +51,16 @@ abstract class BaseExplorer : Explorer {
5151
explorerNetworkDataUpdate.updateWatchAddressData(watchAddress.address, watchAddressBalance)
5252
presenterCallback.updateUi(watchAddressBalance)
5353
}, { error ->
54+
55+
explorerNetworkDataUpdate.staleDataFromError(watchAddress.address)
56+
57+
Observable
58+
.timer(60000, TimeUnit.MILLISECONDS)
59+
.subscribeOn(Schedulers.io())
60+
.subscribe {
61+
startFeed(observable, watchAddress, presenterCallback, explorerNetworkDataUpdate)
62+
}.addTo(balanceDisposables)
63+
5464
error.printStackTrace()
5565
})
5666

app/src/main/java/com/nebulights/coinstacks/Network/BlockExplorers/Explorers.kt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package com.nebulights.coinstacks.Network.BlockExplorers
33
import com.nebulights.coinstacks.Network.BlockExplorers.Model.WatchAddress
44
import com.nebulights.coinstacks.Network.BlockExplorers.Model.WatchAddressBalance
55
import com.nebulights.coinstacks.Network.ValidationCallback
6+
import com.nebulights.coinstacks.Network.exchanges.Exchanges
67
import com.nebulights.coinstacks.Network.exchanges.NetworkCompletionCallback
8+
import com.nebulights.coinstacks.Types.CryptoPairs
79

810
import com.nebulights.coinstacks.Types.CryptoTypes
911

@@ -13,6 +15,8 @@ import com.nebulights.coinstacks.Types.CryptoTypes
1315

1416
interface ExplorerNetworkDataUpdate {
1517
fun updateWatchAddressData(address: String, data: WatchAddressBalance)
18+
fun staleDataFromError(nickname: String)
19+
1620
}
1721

1822
interface Explorer {
@@ -24,15 +28,18 @@ interface Explorer {
2428

2529
object Explorers : ExplorerNetworkDataUpdate {
2630

31+
2732
private var repositories: List<Explorer> = listOf()
2833
private var apiData: MutableMap<String, WatchAddressBalance> = mutableMapOf()
34+
private var staleApiData: MutableMap<String, Boolean> = mutableMapOf()
2935

30-
fun clearAll(){
36+
fun clearAll() {
3137
apiData.clear()
38+
staleApiData.clear()
3239
}
3340

3441
fun loadRepositories(explorerProvider: ExplorerProvider) {
35-
if(repositories.isEmpty()) {
42+
if (repositories.isEmpty()) {
3643
repositories = explorerProvider.getAllRepositories()
3744
}
3845
}
@@ -76,8 +83,21 @@ object Explorers : ExplorerNetworkDataUpdate {
7683

7784
override fun updateWatchAddressData(address: String, data: WatchAddressBalance) {
7885
apiData[address] = data
86+
staleApiData.remove(address)
87+
}
88+
89+
override fun staleDataFromError(address: String) {
90+
staleApiData[address] = true
91+
}
92+
93+
fun isAnyDataStale(): Boolean {
94+
return staleApiData.isNotEmpty()
7995
}
8096

8197
fun getWatchAddressData(): MutableMap<String, WatchAddressBalance> = apiData
8298

99+
fun isRecordStale(address: String?): Boolean{
100+
return (address != null && staleApiData[address] != null)
101+
}
102+
83103
}

app/src/main/java/com/nebulights/coinstacks/Network/exchanges/BaseExchange.kt

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import io.reactivex.android.schedulers.AndroidSchedulers
1111
import io.reactivex.disposables.CompositeDisposable
1212
import io.reactivex.rxkotlin.addTo
1313
import io.reactivex.schedulers.Schedulers
14+
import kotlinx.coroutines.experimental.launch
1415
import retrofit2.HttpException
16+
import java.net.UnknownHostException
1517
import java.util.concurrent.TimeUnit
1618

1719
/**
@@ -45,9 +47,8 @@ abstract class BaseExchange : Exchange {
4547
}
4648

4749
fun <T> startPriceFeed(observable: Observable<T>, delay: Long, ticker: CryptoPairs, presenterCallback: NetworkCompletionCallback, exchangeNetworkDataUpdate: ExchangeNetworkDataUpdate) {
48-
observable.observeOn(AndroidSchedulers.mainThread())
49-
.repeatWhen { result ->result.delay((20000 + delay), TimeUnit.MILLISECONDS) }
50-
.retryWhen { error -> error.delay(20000 + delay, TimeUnit.MILLISECONDS) }
50+
observable.observeOn(AndroidSchedulers.mainThread())
51+
.repeatWhen { result -> result.delay((20000 + delay), TimeUnit.MILLISECONDS) }
5152
.subscribeOn(Schedulers.io())
5253
.subscribe({ result ->
5354
result as NormalizedTickerData
@@ -63,7 +64,15 @@ abstract class BaseExchange : Exchange {
6364
}
6465
}, { error ->
6566
exchangeNetworkDataUpdate.staleDataFromError(ticker)
66-
error.printStackTrace()
67+
presenterCallback.updateUi(ticker)
68+
69+
Observable
70+
.timer(20000, TimeUnit.MILLISECONDS)
71+
.subscribeOn(Schedulers.io())
72+
.subscribe {
73+
startPriceFeed(observable, delay, ticker, presenterCallback, exchangeNetworkDataUpdate)
74+
}.addTo(tickerDisposables)
75+
6776
}).addTo(tickerDisposables)
6877
}
6978

@@ -93,6 +102,14 @@ abstract class BaseExchange : Exchange {
93102
networkCompletionCallback.onNetworkError(exchange.exchange, error.localizedMessage)
94103
}
95104
exchangeNetworkDataUpdate.staleApiDataFromError(exchange.exchange)
105+
106+
Observable
107+
.timer(60000, TimeUnit.MILLISECONDS)
108+
.subscribeOn(Schedulers.io())
109+
.subscribe {
110+
startAccountBalanceFeed(observable, exchange, networkCompletionCallback, exchangeNetworkDataUpdate)
111+
}.addTo(tickerDisposables)
112+
96113
error.printStackTrace()
97114
}).addTo(balanceDisposables)
98115
}

app/src/main/java/com/nebulights/coinstacks/Network/exchanges/ExchangeProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ object ExchangeProvider {
4242

4343
private fun setupOkHttpClient(): OkHttpClient {
4444
val interceptor = HttpLoggingInterceptor()
45-
interceptor.level = HttpLoggingInterceptor.Level.BODY // .BODY for full log output
45+
interceptor.level = HttpLoggingInterceptor.Level.NONE // .BODY for full log output
4646
return OkHttpClient.Builder().addInterceptor(interceptor).build()
4747
}
4848

app/src/main/java/com/nebulights/coinstacks/Network/exchanges/Exchanges.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ interface NetworkCompletionCallback {
2626
fun updateUi(ticker: CryptoPairs)
2727
fun updateUi(apiBalances: ApiBalances)
2828
fun updateUi(watchAddress: WatchAddressBalance)
29-
fun onNetworkError(exchange: String)
29+
fun onNetworkError(exchange: String?)
3030
fun onNetworkError(exchange: String, error: NetworkErrors)
3131
fun onNetworkError(exchange: String, message: String?)
3232
}
@@ -184,7 +184,6 @@ object Exchanges : ExchangeNetworkDataUpdate {
184184

185185
fun isAnyDataStale(): Boolean {
186186
return staleTickerData.isNotEmpty() || this.staleApiData.isNotEmpty()
187-
188187
}
189188

190189
}

app/src/main/java/com/nebulights/coinstacks/Portfolio/Additions/AdditionsActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.os.Bundle
55
import android.preference.PreferenceManager
66
import android.support.v7.app.AppCompatActivity
77
import android.view.MenuItem
8+
import com.nebulights.coinstacks.Common.ConnectionChecker
89
import com.nebulights.coinstacks.Extensions.addFragment
910
import com.nebulights.coinstacks.Network.BlockExplorers.ExplorerProvider
1011
import com.nebulights.coinstacks.Network.BlockExplorers.Explorers
@@ -68,7 +69,7 @@ class AdditionsActivity : AppCompatActivity(), AdditionsContract.Navigator {
6869
val explorers = Explorers
6970
explorers.loadRepositories(ExplorerProvider)
7071

71-
presenter = AdditionsPresenter(additionsFragment, exchanges, explorers, cryptoAssetRepository, this)
72+
presenter = AdditionsPresenter(additionsFragment, exchanges, explorers, cryptoAssetRepository, this, ConnectionChecker(this))
7273

7374

7475
// window.setFlags(WindowManager.LayoutParams.FLAG_SECURE,

app/src/main/java/com/nebulights/coinstacks/Portfolio/Additions/AdditionsPresenter.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.nebulights.coinstacks.Portfolio.Additions
22

3+
import com.nebulights.coinstacks.Common.ConnectionChecker
34
import com.nebulights.coinstacks.Network.BlockExplorers.Explorers
45
import com.nebulights.coinstacks.Network.ValidationCallback
56
import com.nebulights.coinstacks.Network.exchanges.Exchanges
@@ -25,7 +26,8 @@ class AdditionsPresenter(
2526
private var exchanges: Exchanges,
2627
private var explorers: Explorers,
2728
private val cryptoAssetRepository: CryptoAssetContract,
28-
private var navigator: AdditionsContract.Navigator) : AdditionsContract.Presenter {
29+
private var navigator: AdditionsContract.Navigator,
30+
private var connectionChecker: ConnectionChecker) : AdditionsContract.Presenter {
2931

3032

3133
private val TAG = "AdditionsPresenter"
@@ -189,6 +191,12 @@ class AdditionsPresenter(
189191

190192

191193
override fun createWatchAddress(exchange: String, selectedPosition: Int, address: String, nickName: String) {
194+
195+
if(!connectionChecker.isInternetAvailable()){
196+
view.showValidationErrorDialog(connectionChecker.noInternetMessage)
197+
return
198+
}
199+
192200
val userTicker = getTickersForExchange(exchange)[selectedPosition]
193201
val cryptoPair = allTickers.find { ticker -> (ticker.exchange.toLowerCase() == exchange.toLowerCase() && ticker.userTicker() == userTicker) }
194202

@@ -216,6 +224,7 @@ class AdditionsPresenter(
216224
}
217225

218226
override fun createAsset(exchange: String, selectedPosition: Int, quantity: String, price: String) {
227+
219228
val userTicker = getTickersForExchange(exchange)[selectedPosition]
220229
val cryptoPair = allTickers.find { ticker -> (ticker.exchange.toLowerCase() == exchange.toLowerCase() && ticker.userTicker() == userTicker) }
221230

@@ -225,6 +234,12 @@ class AdditionsPresenter(
225234
}
226235

227236
override fun createAPIKey(exchange: String, userName: String, apiPassword: String, apiKey: String, apiSecret: String, cryptoPairs: List<CryptoPairs>) {
237+
238+
if(!connectionChecker.isInternetAvailable()){
239+
view.showValidationErrorDialog(connectionChecker.noInternetMessage)
240+
return
241+
}
242+
228243
val basicAuthentication = BasicAuthentication(exchange, apiKey, apiSecret, apiPassword, userName, listOf())
229244

230245
val startTime = System.currentTimeMillis()

0 commit comments

Comments
 (0)