Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NTV-548: Unable to resolve host "api.kickstarter.com" (#1632)
- Loading branch information
Showing
6 changed files
with
165 additions
and
202 deletions.
There are no files selected for viewing
81 changes: 0 additions & 81 deletions
81
app/src/main/java/com/kickstarter/libs/rx/operators/ApiErrorOperator.java
This file was deleted.
Oops, something went wrong.
60 changes: 60 additions & 0 deletions
60
app/src/main/java/com/kickstarter/libs/rx/operators/ApiErrorOperator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package com.kickstarter.libs.rx.operators | ||
|
||
import com.google.gson.Gson | ||
import com.kickstarter.services.ApiException | ||
import com.kickstarter.services.ResponseException | ||
import com.kickstarter.services.apiresponses.ErrorEnvelope | ||
import retrofit2.Response | ||
import rx.Observable | ||
import rx.Subscriber | ||
import kotlin.Exception | ||
|
||
/** | ||
* Takes a [retrofit2.Response], if it's successful send it to [Subscriber.onNext], otherwise | ||
* attempt to parse the error. | ||
* | ||
* Errors that conform to the API's error format are converted into an [ApiException] exception and sent to | ||
* [Subscriber.onError], otherwise a more generic [ResponseException] is sent to [Subscriber.onError]. | ||
* | ||
* @param <T> The response type. | ||
</T> */ | ||
class ApiErrorOperator<T>(private val gson: Gson?) : Observable.Operator<T, Response<T>> { | ||
override fun call(subscriber: Subscriber<in T?>): Subscriber<in Response<T>> { | ||
val gson = gson | ||
return object : Subscriber<Response<T>?>() { | ||
override fun onCompleted() { | ||
if (!subscriber.isUnsubscribed) { | ||
subscriber.onCompleted() | ||
} | ||
} | ||
|
||
override fun onError(e: Throwable) { | ||
if (!subscriber.isUnsubscribed) { | ||
subscriber.onError(e) | ||
} | ||
} | ||
|
||
override fun onNext(response: Response<T>?) { | ||
if (subscriber.isUnsubscribed) { | ||
return | ||
} | ||
|
||
response?.let { | ||
if (!response?.isSuccessful) { | ||
val envelope: ErrorEnvelope? = try { | ||
gson?.fromJson(response.errorBody()?.string(), ErrorEnvelope::class.java) | ||
} catch (e: Exception) { | ||
null | ||
} | ||
envelope?.let { | ||
subscriber.onError(ApiException(envelope, response)) | ||
} ?: subscriber.onError(ResponseException(response)) | ||
} else { | ||
subscriber.onNext(response.body()) | ||
subscriber.onCompleted() | ||
} | ||
} ?: subscriber.onError(Exception()) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 0 additions & 120 deletions
120
app/src/test/java/com/kickstarter/libs/rx/operators/ApiErrorOperatorTest.java
This file was deleted.
Oops, something went wrong.
100 changes: 100 additions & 0 deletions
100
app/src/test/java/com/kickstarter/libs/rx/operators/ApiErrorOperatorTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package com.kickstarter.libs.rx.operators | ||
|
||
import com.google.gson.Gson | ||
import com.kickstarter.KSRobolectricTestCase | ||
import com.kickstarter.services.apiresponses.ErrorEnvelope | ||
import com.kickstarter.services.apiresponses.ErrorEnvelope.Companion.builder | ||
import okhttp3.MediaType.Companion.toMediaTypeOrNull | ||
import okhttp3.ResponseBody | ||
import okhttp3.ResponseBody.Companion.toResponseBody | ||
import org.junit.Test | ||
import retrofit2.Response | ||
import rx.observers.TestSubscriber | ||
import rx.subjects.PublishSubject | ||
import java.lang.Exception | ||
|
||
class ApiErrorOperatorTest : KSRobolectricTestCase() { | ||
@Test | ||
fun testErrorResponse() { | ||
val gson = Gson() | ||
val response = PublishSubject.create<Response<Int>>() | ||
val result = response.lift(Operators.apiError(gson)) | ||
val resultTest = TestSubscriber<Int>() | ||
result.subscribe(resultTest) | ||
response.onNext(Response.error(400, ResponseBody.create(null, ""))) | ||
resultTest.assertNoValues() | ||
assertEquals(1, resultTest.onErrorEvents.size) | ||
} | ||
|
||
@Test | ||
fun testErrorResponseErrorBodyJSON() { | ||
val gson = Gson() | ||
val response = PublishSubject.create<Response<Int>>() | ||
val result = response.lift(Operators.apiError(gson)) | ||
val resultTest = TestSubscriber<Int>() | ||
result.subscribe(resultTest) | ||
val envelope = builder() | ||
.ksrCode(ErrorEnvelope.TFA_FAILED) | ||
.httpCode(400) | ||
.build() | ||
val jsonString = Gson().toJson(envelope) | ||
response.onNext( | ||
Response.error( | ||
400, | ||
jsonString.toResponseBody("application/json; charset=utf-8".toMediaTypeOrNull()) | ||
) | ||
) | ||
resultTest.assertNoValues() | ||
assertEquals(1, resultTest.onErrorEvents.size) | ||
} | ||
|
||
@Test | ||
fun testErrorResponseBadJSON() { | ||
val gson = Gson() | ||
val response = PublishSubject.create<Response<Int>>() | ||
val result = response.lift(Operators.apiError(gson)) | ||
val resultTest = TestSubscriber<Int>() | ||
result.subscribe(resultTest) | ||
val message = "{malformed json}" | ||
val body = message.toResponseBody("application/json; charset=utf-8".toMediaTypeOrNull()) | ||
response.onNext(Response.error(503, body)) | ||
resultTest.assertNoValues() | ||
assertEquals(1, resultTest.onErrorEvents.size) | ||
} | ||
|
||
@Test | ||
fun testResponseNull() { | ||
val gson = Gson() | ||
val response = PublishSubject.create<Response<Int>?>() | ||
val result = response.lift(Operators.apiError(gson)) | ||
val resultTest = TestSubscriber<Int>() | ||
result.subscribe(resultTest) | ||
response.onNext(null) | ||
resultTest.assertNoValues() | ||
assertEquals(1, resultTest.onErrorEvents.size) | ||
} | ||
|
||
@Test | ||
fun testExceptionErrorResponse() { | ||
val gson = Gson() | ||
val response = PublishSubject.create<Response<Int>>() | ||
val result = response.lift(Operators.apiError(gson)) | ||
val resultTest = TestSubscriber<Int>() | ||
result.subscribe(resultTest) | ||
response.onError(Exception()) | ||
resultTest.assertNoValues() | ||
assertEquals(1, resultTest.onErrorEvents.size) | ||
} | ||
|
||
@Test | ||
fun testSuccessResponse() { | ||
val gson = Gson() | ||
val response = PublishSubject.create<Response<Int>>() | ||
val result = response.lift(Operators.apiError(gson)) | ||
val resultTest = TestSubscriber<Int>() | ||
result.subscribe(resultTest) | ||
response.onNext(Response.success(42)) | ||
resultTest.assertValues(42) | ||
resultTest.assertCompleted() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters