Skip to content

Commit 5279400

Browse files
authored
handle exceptions (#106)
1 parent 6e9cb2b commit 5279400

File tree

21 files changed

+121
-32
lines changed

21 files changed

+121
-32
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ jobs:
1818
os: ubuntu
1919
- target: jsNode
2020
os: ubuntu
21-
# TODO: wasmJs times out on bulk tests
22-
# - target: wasmJsBrowser
23-
# os: ubuntu
21+
- target: wasmJsBrowser
22+
os: ubuntu
2423
- target: wasmJsNode
2524
os: ubuntu
2625
- target: linuxX64

justfile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ set windows-shell := ["C:\\Program Files\\Git\\bin\\sh.exe", "-c"]
33
_default:
44
just --list
55

6+
test-server-cmd := "npx -y http-server src/commonTest/resources/data -e json -p 8080 --cors"
7+
8+
# Serve PokeAPI data from static files
69
test-server:
7-
npx -y http-server src/commonTest/resources/data -e json -p 8080 --cors
10+
{{ test-server-cmd }}
811

12+
# Spawn a background job serving PokeAPI data from static files
913
test-server-background:
10-
npx -y http-server src/commonTest/resources/data -e json -p 8080 --cors &
14+
{{ test-server-cmd }} &

src/appleMain/kotlin/dev/sargunv/pokekotlin/util/getDefaultEngine.apple.kt renamed to src/appleMain/kotlin/dev/sargunv/pokekotlin/internal/getDefaultEngine.apple.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.sargunv.pokekotlin.util
1+
package dev.sargunv.pokekotlin.internal
22

33
import io.ktor.client.engine.darwin.Darwin
44

src/commonMain/kotlin/dev/sargunv/pokekotlin/client/PokeApi.kt renamed to src/commonMain/kotlin/dev/sargunv/pokekotlin/PokeApi.kt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
package dev.sargunv.pokekotlin.client
1+
@file:JvmName("PokeApiClient")
2+
3+
package dev.sargunv.pokekotlin
24

35
import de.jensklingenberg.ktorfit.Ktorfit.Builder
46
import de.jensklingenberg.ktorfit.http.GET
57
import de.jensklingenberg.ktorfit.http.Path
68
import de.jensklingenberg.ktorfit.http.Query
9+
import dev.sargunv.pokekotlin.internal.PokeApiConverter
10+
import dev.sargunv.pokekotlin.internal.PokeApiJson
11+
import dev.sargunv.pokekotlin.internal.getDefaultEngine
712
import dev.sargunv.pokekotlin.model.Ability
813
import dev.sargunv.pokekotlin.model.ApiResourceList
914
import dev.sargunv.pokekotlin.model.Berry
@@ -55,14 +60,15 @@ import dev.sargunv.pokekotlin.model.SuperContestEffect
5560
import dev.sargunv.pokekotlin.model.Type
5661
import dev.sargunv.pokekotlin.model.Version
5762
import dev.sargunv.pokekotlin.model.VersionGroup
58-
import dev.sargunv.pokekotlin.util.getDefaultEngine
5963
import io.ktor.client.HttpClient
6064
import io.ktor.client.HttpClientConfig
6165
import io.ktor.client.engine.HttpClientEngine
6266
import io.ktor.client.plugins.cache.HttpCache
6367
import io.ktor.client.plugins.cache.storage.CacheStorage
6468
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
69+
import io.ktor.http.ContentType
6570
import io.ktor.serialization.kotlinx.json.json
71+
import kotlin.jvm.JvmName
6672

6773
interface PokeApi {
6874

@@ -557,6 +563,7 @@ interface PokeApi {
557563
companion object : PokeApi by PokeApi()
558564
}
559565

566+
@JvmName("create")
560567
fun PokeApi(
561568
baseUrl: String = "https://pokeapi.co/api/v2/",
562569
engine: HttpClientEngine = getDefaultEngine(),
@@ -567,10 +574,11 @@ fun PokeApi(
567574
.baseUrl(baseUrl)
568575
.httpClient(
569576
HttpClient(engine) {
570-
this.configure()
571-
this.install(HttpCache) { cacheStorage?.let { privateStorage(it) } }
572-
this.install(ContentNegotiation) { json(PokeApiJson) }
577+
configure()
578+
install(HttpCache) { cacheStorage?.let { privateStorage(it) } }
579+
install(ContentNegotiation) { json(PokeApiJson, ContentType.Any) }
573580
}
574581
)
582+
.converterFactories(PokeApiConverter.Factory)
575583
.build()
576584
.createPokeApi()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package dev.sargunv.pokekotlin
2+
3+
import io.ktor.http.HttpStatusCode
4+
5+
sealed class PokeApiException : Throwable {
6+
constructor(message: String) : super(message)
7+
8+
constructor(cause: Throwable) : super(cause)
9+
10+
class HttpStatus(val status: HttpStatusCode) : PokeApiException(status.toString())
11+
12+
class UnknownException(cause: Throwable) : PokeApiException(cause)
13+
}

src/commonMain/kotlin/dev/sargunv/pokekotlin/client/PokeApiError.kt

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/commonMain/kotlin/dev/sargunv/pokekotlin/util/DelegatingSerializer.kt renamed to src/commonMain/kotlin/dev/sargunv/pokekotlin/internal/DelegatingSerializer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.sargunv.pokekotlin.util
1+
package dev.sargunv.pokekotlin.internal
22

33
import kotlinx.serialization.KSerializer
44
import kotlinx.serialization.descriptors.SerialDescriptor
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package dev.sargunv.pokekotlin.internal
2+
3+
import de.jensklingenberg.ktorfit.Ktorfit
4+
import de.jensklingenberg.ktorfit.converter.Converter
5+
import de.jensklingenberg.ktorfit.converter.KtorfitResult
6+
import de.jensklingenberg.ktorfit.converter.TypeData
7+
import dev.sargunv.pokekotlin.PokeApiException
8+
import io.ktor.client.call.body
9+
import io.ktor.client.statement.HttpResponse
10+
import io.ktor.http.isSuccess
11+
12+
internal class PokeApiConverter(private val typeData: TypeData) :
13+
Converter.SuspendResponseConverter<HttpResponse, Any> {
14+
override suspend fun convert(result: KtorfitResult): Any {
15+
return when (result) {
16+
is KtorfitResult.Failure -> throw PokeApiException.UnknownException(result.throwable)
17+
is KtorfitResult.Success -> {
18+
val status = result.response.status
19+
when {
20+
status.isSuccess() -> result.response.body<Any>(typeData.typeInfo)
21+
else -> throw PokeApiException.HttpStatus(status)
22+
}
23+
}
24+
}
25+
}
26+
27+
internal object Factory : Converter.Factory {
28+
override fun suspendResponseConverter(
29+
typeData: TypeData,
30+
ktorfit: Ktorfit,
31+
): Converter.SuspendResponseConverter<HttpResponse, Any> = PokeApiConverter(typeData)
32+
}
33+
}

src/commonMain/kotlin/dev/sargunv/pokekotlin/client/PokeApiJson.kt renamed to src/commonMain/kotlin/dev/sargunv/pokekotlin/internal/PokeApiJson.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
package dev.sargunv.pokekotlin.client
1+
package dev.sargunv.pokekotlin.internal
22

33
import kotlinx.serialization.ExperimentalSerializationApi
44
import kotlinx.serialization.json.Json
55
import kotlinx.serialization.json.JsonNamingStrategy
66

77
@OptIn(ExperimentalSerializationApi::class)
8-
val PokeApiJson = Json {
8+
internal val PokeApiJson = Json {
99
prettyPrint = true
1010
ignoreUnknownKeys = true
1111
namingStrategy = JsonNamingStrategy.SnakeCase

src/commonMain/kotlin/dev/sargunv/pokekotlin/util/getDefaultEngine.kt renamed to src/commonMain/kotlin/dev/sargunv/pokekotlin/internal/getDefaultEngine.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.sargunv.pokekotlin.util
1+
package dev.sargunv.pokekotlin.internal
22

33
import io.ktor.client.engine.HttpClientEngine
44

0 commit comments

Comments
 (0)