Skip to content

Commit

Permalink
Add Ktor Either support
Browse files Browse the repository at this point in the history
  • Loading branch information
Davide Farella committed Oct 24, 2020
1 parent d13741c commit 8c7e850
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 3 deletions.
8 changes: 5 additions & 3 deletions network/src/commonMain/kotlin/network/di.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package network

import io.ktor.client.*
import io.ktor.client.engine.*
import io.ktor.client.features.json.*
import io.ktor.client.HttpClient
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.features.json.JsonFeature
import kotlinx.serialization.json.Json
import org.koin.core.qualifier.named
import org.koin.dsl.module

Expand All @@ -18,6 +19,7 @@ val networkModule = module {
// logger = Logger.SIMPLE
// level = LogLevel.INFO
// }
withEitherValidator()
}
}
}
Expand Down
33 changes: 33 additions & 0 deletions network/src/commonMain/kotlin/network/ktorEitherSupport.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package network

import entities.Either
import entities.Left
import entities.NetworkError
import entities.Right
import io.ktor.client.HttpClientConfig
import io.ktor.client.features.HttpResponseValidator

/**
* Catch [KtorEitherException] for create an [Either]
* @return [Either] of [NetworkError] and [B]
*/
inline fun <B> Either.Companion.Try(block: () -> B): Either<NetworkError, B> =
try {
Right(block())
} catch (e: KtorEitherException) {
Left(e.reason)
}

internal fun HttpClientConfig<*>.withEitherValidator() =
HttpResponseValidator {
validateResponse { response ->
val error = when (response.status.value) {
404 -> NetworkError.NotFound
else -> null
}
error?.let { throw KtorEitherException(it) }
}
}

@PublishedApi
internal class KtorEitherException(val reason: NetworkError): Throwable(reason.toString())
57 changes: 57 additions & 0 deletions network/src/jvmTest/kotlin/network/KtorEitherSupportTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package network

import assert4k.*
import entities.Either
import entities.NetworkError
import entities.left
import entities.right
import io.ktor.client.HttpClient
import io.ktor.client.engine.mock.MockEngine
import io.ktor.client.engine.mock.respond
import io.ktor.client.request.get
import io.ktor.http.HttpStatusCode
import io.ktor.http.fullPath
import util.test.CoroutinesTest
import kotlin.test.*

internal class KtorEitherSupportTest: CoroutinesTest {

class TestService(private val client: HttpClient) {

suspend fun success() = Either.Try {
client.get<String>("success")
}

suspend fun notFound() = Either.Try {
client.get<String>("not_found")
}
}

private val client = HttpClient(MockEngine) {
engine {
addHandler { request ->

val url = request.url.fullPath.substringAfter('/')
fun error(code: Int) = respond("url", HttpStatusCode(code, url))

when (url) {
"success" -> respond("hello")
"not_found" -> error(404)
else -> error("Unhandled $url")
}
}
}
withEitherValidator()
}
private val service = TestService(client)

@Test
fun `correctly create an Either of String`() = coroutinesTest {
assert that service.success() equals "hello".right()
}

@Test
fun `correctly create an Either of NotFound error`() = coroutinesTest {
assert that service.notFound() equals NetworkError.NotFound.left()
}
}

0 comments on commit 8c7e850

Please sign in to comment.