Skip to content

Commit

Permalink
fix: Add error utils, fix stripe error message and charge data class
Browse files Browse the repository at this point in the history
  • Loading branch information
liveHarshit committed Aug 14, 2019
1 parent 27471d8 commit 83bba15
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 1 deletion.
Expand Up @@ -24,6 +24,7 @@ import org.fossasia.openevent.general.order.OrderService
import org.fossasia.openevent.general.settings.SettingsService
import org.fossasia.openevent.general.ticket.Ticket
import org.fossasia.openevent.general.ticket.TicketService
import org.fossasia.openevent.general.utils.ErrorUtils
import org.fossasia.openevent.general.utils.HttpErrors
import retrofit2.HttpException
import timber.log.Timber
Expand All @@ -39,6 +40,8 @@ const val PAYMENT_MODE_ONSITE = "onsite"
const val PAYMENT_MODE_CHEQUE = "cheque"
const val PAYMENT_MODE_PAYPAL = "paypal"
const val PAYMENT_MODE_STRIPE = "stripe"
private const val ERRORS = "errors"
private const val DETAIL = "detail"
private const val ORDER_EXPIRY_TIME = 15

class AttendeeViewModel(
Expand Down Expand Up @@ -354,7 +357,7 @@ class AttendeeViewModel(
Timber.d("Failed charging the user")
}
}, {
mutableMessage.value = resource.getString(R.string.payment_not_complete_message)
mutableMessage.value = ErrorUtils.getErrorDetails(it).detail
Timber.d(it, "Failed charging the user")
})
}
Expand Down
@@ -1,10 +1,13 @@
package org.fossasia.openevent.general.order

import com.fasterxml.jackson.databind.PropertyNamingStrategy
import com.fasterxml.jackson.databind.annotation.JsonNaming
import com.github.jasminb.jsonapi.IntegerIdHandler
import com.github.jasminb.jsonapi.annotations.Id
import com.github.jasminb.jsonapi.annotations.Type

@Type("charge")
@JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class)
data class Charge(
@Id(IntegerIdHandler::class)
val id: Int,
Expand Down
31 changes: 31 additions & 0 deletions app/src/main/java/org/fossasia/openevent/general/utils/Error.kt
@@ -0,0 +1,31 @@
package org.fossasia.openevent.general.utils

import org.fossasia.openevent.general.utils.StringUtils.isEmpty

class Error {

var title: String? = null
var detail: String? = null
var pointer: String? = null

override fun toString(): String {

if (isEmpty(title)) {
if (!isEmpty(detail)) {
return (if (isEmpty(pointer)) {
detail
} else {
"$detail - $pointer"
}).toString()
}
} else {
return if (isEmpty(pointer)) {
"$title: $detail"
} else {
"$title: $detail - $pointer"
}
}

return ""
}
}
118 changes: 118 additions & 0 deletions app/src/main/java/org/fossasia/openevent/general/utils/ErrorUtils.kt
@@ -0,0 +1,118 @@
package org.fossasia.openevent.general.utils

import timber.log.Timber
import org.json.JSONObject
import org.fossasia.openevent.general.utils.HttpErrors.BAD_REQUEST
import org.fossasia.openevent.general.utils.HttpErrors.CONFLICT
import org.fossasia.openevent.general.utils.HttpErrors.FORBIDDEN
import org.fossasia.openevent.general.utils.HttpErrors.METHOD_NOT_ALLOWED
import org.fossasia.openevent.general.utils.HttpErrors.NOT_FOUND
import org.fossasia.openevent.general.utils.HttpErrors.REQUEST_TIMEOUT
import org.fossasia.openevent.general.utils.HttpErrors.UNAUTHORIZED
import org.fossasia.openevent.general.utils.HttpErrors.UNPROCESSABLE_ENTITY
import org.fossasia.openevent.general.utils.StringUtils.isEmpty
import retrofit2.HttpException

const val ERRORS = "errors"
const val SOURCE = "source"
const val POINTER = "pointer"
const val DETAIL = "detail"
const val TITLE = "title"

const val POINTER_LENGTH = 3

object ErrorUtils {

fun getMessage(throwable: Throwable): Error {
var error = Error()
if (throwable is HttpException) {
when (throwable.code()) {
BAD_REQUEST,
UNAUTHORIZED,
FORBIDDEN,
NOT_FOUND,
METHOD_NOT_ALLOWED,
REQUEST_TIMEOUT -> error = getErrorTitleAndDetails(throwable)
UNPROCESSABLE_ENTITY,
CONFLICT -> error = getErrorDetails(throwable)
else -> error.detail = throwable.message
}
return error
}

if (isEmpty(error.detail))
error.detail = throwable.message
return error
}

fun getErrorDetails(throwable: Throwable): Error {
val error = Error()
if (throwable is HttpException) {
val responseBody = throwable.response()?.errorBody()

try {
val jsonObject = JSONObject(responseBody?.string())
val jsonArray = JSONObject(jsonObject.getJSONArray(ERRORS).get(0).toString())
val errorSource = JSONObject(jsonArray.get(SOURCE).toString())

try {
val pointedField = getPointedField(errorSource.getString(POINTER))
if (pointedField == null) {
error.detail = jsonArray.get(DETAIL).toString()
} else {
error.pointer = pointedField
error.detail = jsonArray.get(DETAIL).toString().replace(".", "")
}
} catch (e: Exception) {
error.detail = jsonArray.get(DETAIL).toString()
}
} catch (e: Exception) {
Timber.e(e)
}
}
return error
}

fun getErrorTitleAndDetails(throwable: Throwable): Error {
val error = Error()
if (throwable is HttpException) {
val responseBody = throwable.response()?.errorBody()

try {
val jsonObject = JSONObject(responseBody?.string())
val jsonArray = JSONObject(jsonObject.getJSONArray(ERRORS).get(0).toString())
val errorSource = JSONObject(jsonArray.get(SOURCE).toString())

try {
val pointedField = getPointedField(errorSource.getString(POINTER))

if (pointedField == null) {
error.detail = jsonArray.get(DETAIL).toString()
} else {
error.pointer = pointedField
error.detail = jsonArray.get(DETAIL).toString().replace(".", "")
}
error.title = jsonArray.get(TITLE).toString()
} catch (e: Exception) {
error.title = jsonArray.get(TITLE).toString()
error.detail = jsonArray.get(DETAIL).toString()
}
} catch (e: Exception) {
Timber.e(e)
}
}
return error
}

fun getPointedField(pointerString: String?): String? {
return if (pointerString == null || isEmpty(pointerString))
null
else {
val path = pointerString.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
if (path.size > POINTER_LENGTH)
path[path.size - 1]
else
null
}
}
}
Expand Up @@ -4,4 +4,9 @@ object HttpErrors {
const val CONFLICT = 409
const val UNAUTHORIZED = 401
const val NOT_FOUND = 404
const val BAD_REQUEST = 400
const val FORBIDDEN = 403
const val METHOD_NOT_ALLOWED = 405
const val REQUEST_TIMEOUT = 408
const val UNPROCESSABLE_ENTITY = 422
}
Expand Up @@ -133,4 +133,8 @@ object StringUtils {
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) // -1 so that we don't include "." in the link
return paragraph
}

fun isEmpty(str: CharSequence?): Boolean {
return str.isNullOrEmpty()
}
}

0 comments on commit 83bba15

Please sign in to comment.