{"id":13565794,"url":"https://github.com/gildor/kotlin-coroutines-okhttp","last_synced_at":"2026-01-05T12:13:22.512Z","repository":{"id":39617144,"uuid":"91376377","full_name":"gildor/kotlin-coroutines-okhttp","owner":"gildor","description":"Kotlin Coroutines await() extension for OkHttp Call","archived":false,"fork":false,"pushed_at":"2024-05-10T17:02:15.000Z","size":197,"stargazers_count":185,"open_issues_count":2,"forks_count":14,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-26T14:41:15.547Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gildor.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-15T19:24:24.000Z","updated_at":"2025-03-18T18:38:14.000Z","dependencies_parsed_at":"2024-08-01T13:22:36.472Z","dependency_job_id":"b205d9fa-8c8e-4e62-9795-5ad5ef06f2d9","html_url":"https://github.com/gildor/kotlin-coroutines-okhttp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gildor%2Fkotlin-coroutines-okhttp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gildor%2Fkotlin-coroutines-okhttp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gildor%2Fkotlin-coroutines-okhttp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gildor%2Fkotlin-coroutines-okhttp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gildor","download_url":"https://codeload.github.com/gildor/kotlin-coroutines-okhttp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247097586,"owners_count":20883121,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:01:55.615Z","updated_at":"2026-01-05T12:13:22.481Z","avatar_url":"https://github.com/gildor.png","language":"Kotlin","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"readme":"# Kotlin coroutines await extension for OkHttp3\n\nThis is small library that provides `await()` extension for [okhttp3.Call](https://square.github.io/okhttp/3.x/okhttp/okhttp3/Call.html) for integration with Kotlin coroutines\n\nBased on [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) implementation.\n\nRequires Kotlin 1.3+\n\nDepends on [OkHttp3 3.8.0](https://github.com/square/okhttp/blob/master/CHANGELOG.md#version-380) so don't require updates to [newest version of OkHttp](https://github.com/square/okhttp/blob/master/CHANGELOG.md#version-3130) that require Java 8+ or Android 5+\n\n## Usage\n\n```kotlin\n// Create OkHttp client\nval client = OkHttpClient.Builder().build()\n// Create request \nval request = Request.Builder().url(\"https://example.org/\").build()\n\nsuspend fun main() {\n    // Do call and await() for result from any suspend function\n    val result = client.newCall(request).await()\n    println(\"${result.code()}: ${result.message()}\")\n}\n```\n\nThis library doesn't provide any facilities for non-blocking read of response body,\nif you need a way to do that consider to use `withContext(Dispatchers.IO)` and wrap blocking calls.\n\nSee this issue about support of non-blocking API for Okio - https://github.com/square/okio/issues/501\n\n## Download\n\nDownload the [JAR](https://bintray.com/gildor/maven/kotlin-coroutines-okhttp#files/ru/gildor/coroutines/kotlin-coroutines-okhttp):\n\nArtifacts are available on [JCenter](https://bintray.com/gildor/maven/kotlin-coroutines-okhttp) and [Maven Central](https://search.maven.org/search?q=a:kotlin-coroutines-okhttp)\n\nGradle:\n\n```kotlin\nimplementation(\"ru.gildor.coroutines:kotlin-coroutines-okhttp:1.0\")\n```\n\nMaven:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eru.gildor.coroutines\u003c/groupId\u003e\n  \u003cartifactId\u003ekotlin-coroutines-okhttp\u003c/artifactId\u003e\n  \u003cversion\u003e1.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Debugging\n\nBecause this coroutines adapter uses async API of OkHttp by default \nstacktrace doesn't contain link on code that called it.\n\nFor example you have code from Usage section code that throws SocketTimeoutException\n\nIf you run it you will get stacktrace similar to this:\n\n```\nException in thread \"main\" java.net.SocketTimeoutException: Read timed out\n\tat java.base/java.net.SocketInputStream.socketRead0(Native Method)\n\tat java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)\n\t...\n```\n\nAs you can see, there is no way to understand from which line or class this request was started.\n \nYou should understand, this is not something unique for Kotlin coroutines or this adapter,\nyou would have the same stacktrace with `okhttp3.Callback` if would throw an exception on failure\nTo make this stacktrace more useful you can do a few things\n\n### Wrap exception manually:\n```kotlin\nsuspend fun main() {\n   try {\n       client.newCall(request).await()\n   } catch (e: IOException) {\n       // Catch original exception\n       // Use some logger that will write line number to logs, so you can find the source of exception\n       someLogger.error(e)\n       // or just wrap exception and throw it to get stacktrace\n       throw IOException(\"Some additional debug info: ${e.message}\", e)\n   }\n}\n```\n\nThis will give you stacktrace that shows line where exception was rethrown or logged:\n```kotlin\nException in thread \"main\" java.io.IOException: java.net.SocketTimeoutException: Read timed out\n    at ru.gildor.coroutines.okhttp.MainKt.main(main.kt:20)\n    at ru.gildor.coroutines.okhttp.MainKt$main$1.invokeSuspend(main.kt)\n...\nCaused by: java.net.SocketTimeoutException: Read timed out\n    at java.base/java.net.SocketInputStream.socketRead0(Native Method)\n    at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)\n...\n```\n    \n### Enable debug mode of kotlinx.coroutines:\n\n```kotlin\n// Set it before first usage of coroutines in your project\nSystem.setProperty(DEBUG_PROPERTY_NAME, DEBUG_PROPERTY_VALUE_ON)\n```\n\nThis will allow you to see line where request is started:\n\n```\nException in thread \"main\" java.net.SocketTimeoutException\n    (Coroutine boundary)\n    at ru.gildor.coroutines.okhttp.MainKt.main(main.kt:15)\nCaused by: java.net.SocketTimeoutException: timeout\n    at okio.Okio$4.newTimeoutException(Okio.java:230)\n    at okio.AsyncTimeout.exit(AsyncTimeout.java:285)\n...\n```\n\nThis will give you coroutines stack so you can debug it in most cases\n    \n### Enable stack recording\n\nTo help debug some complicated cases, \nwhen you want to know which code started coroutine, \n`await()` provides argument recordStack:\n\n```kotin\nsuspend fun main() {\n    client.newCall(request).await(recordStack = true)\n}\n```\n\nInstead of recovering coroutine stacktrace this call will create exception on method call to save stack\nand will throw it on error, so you will get detailed stack \n\n```\nException in thread \"main\" java.io.IOException\n\tat ru.gildor.coroutines.okhttp.MainKt.main(main.kt:15)\n\t...\nCaused by: java.net.SocketTimeoutException: timeout\n\tat okio.Okio$4.newTimeoutException(Okio.java:230)\n\t...\n```\n\nBy default stack recording is disabled, but you can enable it using system properties\n(should set it before first usage of the adapter):\n\n```kotlin\nSystem.setProperty(OKHTTP_STACK_RECORDER_PROPERTY, OKHTTP_STACK_RECORDER_ON)\n```\n\nBut this method is relatively heavyweight because creates exception on each request \n(even successful, because we have to record stacktrace before invocation) \nand resulting stacktrace is full of coroutines internal calls, \n\nSo I recommend to use it only if you have hard times to understand what is caused the problem and you need all information\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgildor%2Fkotlin-coroutines-okhttp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgildor%2Fkotlin-coroutines-okhttp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgildor%2Fkotlin-coroutines-okhttp/lists"}