From ffc78da700c5665786d2838752d8465e1b07c72f Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 23 Apr 2020 11:52:04 -0300 Subject: [cashier] add offline detection to all failing HTTP requests and show a better error message in these cases --- .../main/java/net/taler/cashier/ConfigFragment.kt | 3 ++ .../src/main/java/net/taler/cashier/HttpHelper.kt | 2 +- .../main/java/net/taler/cashier/MainViewModel.kt | 7 +++- .../taler/cashier/withdraw/TransactionFragment.kt | 23 +++++++------ .../net/taler/cashier/withdraw/WithdrawManager.kt | 40 +++++++++++++++------- 5 files changed, 50 insertions(+), 25 deletions(-) (limited to 'cashier/src/main/java') diff --git a/cashier/src/main/java/net/taler/cashier/ConfigFragment.kt b/cashier/src/main/java/net/taler/cashier/ConfigFragment.kt index f435883..501eed7 100644 --- a/cashier/src/main/java/net/taler/cashier/ConfigFragment.kt +++ b/cashier/src/main/java/net/taler/cashier/ConfigFragment.kt @@ -131,6 +131,9 @@ class ConfigFragment : Fragment() { val action = ConfigFragmentDirections.actionConfigFragmentToBalanceFragment() findNavController().navigate(action) } + ConfigResult.Offline -> { + Snackbar.make(view!!, R.string.config_error_offline, LENGTH_LONG).show() + } is ConfigResult.Error -> { if (result.authError) { Snackbar.make(view!!, R.string.config_error_auth, LENGTH_LONG).show() diff --git a/cashier/src/main/java/net/taler/cashier/HttpHelper.kt b/cashier/src/main/java/net/taler/cashier/HttpHelper.kt index 49a43d1..003c2f6 100644 --- a/cashier/src/main/java/net/taler/cashier/HttpHelper.kt +++ b/cashier/src/main/java/net/taler/cashier/HttpHelper.kt @@ -112,7 +112,7 @@ object HttpHelper { sealed class HttpJsonResult { class Error(val statusCode: Int, private val errorMsg: String? = null) : HttpJsonResult() { val msg: String - get() = errorMsg?.let { "\n\n$statusCode $it" } ?: ": $statusCode" + get() = errorMsg?.let { "\n\n$statusCode $it" } ?: "$statusCode" } class Success(val json: JSONObject) : HttpJsonResult() diff --git a/cashier/src/main/java/net/taler/cashier/MainViewModel.kt b/cashier/src/main/java/net/taler/cashier/MainViewModel.kt index 3587e95..c8d9a3b 100644 --- a/cashier/src/main/java/net/taler/cashier/MainViewModel.kt +++ b/cashier/src/main/java/net/taler/cashier/MainViewModel.kt @@ -103,7 +103,11 @@ class MainViewModel(private val app: Application) : AndroidViewModel(app) { } } is HttpJsonResult.Error -> { - ConfigResult.Error(response.statusCode == 401, response.msg) + if (response.statusCode > 0 && app.isOnline()) { + ConfigResult.Error(response.statusCode == 401, response.msg) + } else { + ConfigResult.Offline + } } } mConfigResult.postValue(result) @@ -156,5 +160,6 @@ data class Config( sealed class ConfigResult { class Error(val authError: Boolean, val msg: String) : ConfigResult() + object Offline : ConfigResult() object Success : ConfigResult() } diff --git a/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt b/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt index e433540..0726a77 100644 --- a/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt +++ b/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt @@ -36,6 +36,7 @@ import net.taler.cashier.withdraw.WithdrawResult.Error import net.taler.cashier.withdraw.WithdrawResult.InsufficientBalance import net.taler.cashier.withdraw.WithdrawResult.Success import net.taler.common.NfcManager +import net.taler.common.exhaustive import net.taler.common.fadeIn import net.taler.common.fadeOut @@ -101,16 +102,9 @@ class TransactionFragment : Fragment() { .start() } when (result) { - is InsufficientBalance -> { - val c = getColor(requireContext(), R.color.design_default_color_error) - introView.setTextColor(c) - introView.text = getString(R.string.withdraw_error_insufficient_balance) - } - is Error -> { - val c = getColor(requireContext(), R.color.design_default_color_error) - introView.setTextColor(c) - introView.text = result.msg - } + is InsufficientBalance -> setErrorMsg(getString(R.string.withdraw_error_insufficient_balance)) + is WithdrawResult.Offline -> setErrorMsg(getString(R.string.withdraw_error_offline)) + is Error -> setErrorMsg(result.msg) is Success -> { // start NFC nfcManager.setTagString(result.talerUri) @@ -129,7 +123,14 @@ class TransactionFragment : Fragment() { .setDuration(750) .start() } - } + null -> return + }.exhaustive + } + + private fun setErrorMsg(str: String) { + val c = getColor(requireContext(), R.color.design_default_color_error) + introView.setTextColor(c) + introView.text = str } private fun onWithdrawStatusChanged(status: WithdrawStatus?): Any = when (status) { diff --git a/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt b/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt index 32e0802..59e0c50 100644 --- a/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt +++ b/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt @@ -36,6 +36,7 @@ import net.taler.cashier.MainViewModel import net.taler.cashier.R import net.taler.common.Amount import net.taler.common.QrCodeManager.makeQrCode +import net.taler.common.isOnline import org.json.JSONObject import java.util.concurrent.TimeUnit.MINUTES import java.util.concurrent.TimeUnit.SECONDS @@ -90,22 +91,27 @@ class WithdrawManager( Log.d(TAG, "Starting withdrawal at $url") val map = mapOf("amount" to amount.toJSONString()) val body = JSONObject(map) - when (val result = makeJsonPostRequest(url, body, config)) { + val result = when (val response = makeJsonPostRequest(url, body, config)) { is Success -> { - val talerUri = result.json.getString("taler_withdraw_uri") + val talerUri = response.json.getString("taler_withdraw_uri") val withdrawResult = WithdrawResult.Success( - id = result.json.getString("withdrawal_id"), + id = response.json.getString("withdrawal_id"), talerUri = talerUri, qrCode = makeQrCode(talerUri) ) - mWithdrawResult.postValue(withdrawResult) - timer.start() + withdrawResult } is Error -> { - val errorStr = app.getString(R.string.withdraw_error_fetch, result.msg) - mWithdrawResult.postValue(WithdrawResult.Error(errorStr)) + if (response.statusCode > 0 && app.isOnline()) { + val errorStr = app.getString(R.string.withdraw_error_fetch, response.msg) + WithdrawResult.Error(errorStr) + } else { + WithdrawResult.Offline + } } } + mWithdrawResult.postValue(result) + if (result is WithdrawResult.Success) timer.start() } } @@ -125,8 +131,12 @@ class WithdrawManager( override fun onFinish() { abort() - val str = app.getString(R.string.withdraw_error_timeout) - mWithdrawStatus.postValue(WithdrawStatus.Error(str)) + val result = if (app.isOnline()) { + WithdrawStatus.Error(app.getString(R.string.withdraw_error_timeout)) + } else { + WithdrawStatus.Error(app.getString(R.string.withdraw_error_offline)) + } + mWithdrawStatus.postValue(result) cancel() } } @@ -191,13 +201,18 @@ class WithdrawManager( val url = "${config.bankUrl}/accounts/${config.username}/withdrawals/${withdrawalId}/confirm" Log.d(TAG, "Confirming withdrawal at $url") - when (val result = makeJsonPostRequest(url, JSONObject(), config)) { + when (val response = makeJsonPostRequest(url, JSONObject(), config)) { is Success -> { // no-op still waiting for [timer] to confirm our confirmation } is Error -> { - Log.e(TAG, "Error confirming withdrawal. Status code: ${result.statusCode}") - mWithdrawStatus.postValue(WithdrawStatus.Error(result.msg)) + Log.e(TAG, "Error confirming withdrawal. Status code: ${response.statusCode}") + val result = if (response.statusCode > 0 && app.isOnline()) { + WithdrawStatus.Error(response.msg) + } else { + WithdrawStatus.Error(app.getString(R.string.withdraw_error_offline)) + } + mWithdrawStatus.postValue(result) } } } @@ -216,6 +231,7 @@ class WithdrawManager( sealed class WithdrawResult { object InsufficientBalance : WithdrawResult() + object Offline : WithdrawResult() class Error(val msg: String) : WithdrawResult() class Success(val id: String, val talerUri: String, val qrCode: Bitmap) : WithdrawResult() } -- cgit v1.2.3