• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

gildor/kotlin-coroutines-okhttp: Kotlin Coroutines await() extension for OkHttp ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称(OpenSource Name):

gildor/kotlin-coroutines-okhttp

开源软件地址(OpenSource Url):

https://github.com/gildor/kotlin-coroutines-okhttp

开源编程语言(OpenSource Language):

Kotlin 100.0%

开源软件介绍(OpenSource Introduction):

Kotlin coroutines await extension for OkHttp3

This is small library that provides await() extension for okhttp3.Call for integration with Kotlin coroutines

Based on kotlinx.coroutines implementation.

Requires Kotlin 1.3+

Depends on OkHttp3 3.8.0 so don't require updates to newest version of OkHttp that require Java 8+ or Android 5+

Usage

// Create OkHttp client
val client = OkHttpClient.Builder().build()
// Create request 
val request = Request.Builder().url("https://example.org/").build()

suspend fun main() {
    // Do call and await() for result from any suspend function
    val result = client.newCall(request).await()
    println("${result.code()}: ${result.message()}")
}

This library doesn't provide any facilities for non-blocking read of response body, if you need a way to do that consider to use withContext(Dispatchers.IO) and wrap blocking calls.

See this issue about support of non-blocking API for Okio - square/okio#501

Download

Download the JAR:

Artifacts are available on JCenter and Maven Central

Gradle:

implementation("ru.gildor.coroutines:kotlin-coroutines-okhttp:1.0")

Maven:

<dependency>
  <groupId>ru.gildor.coroutines</groupId>
  <artifactId>kotlin-coroutines-okhttp</artifactId>
  <version>1.0</version>
</dependency>

Debugging

Because this coroutines adapter uses async API of OkHttp by default stacktrace doesn't contain link on code that called it.

For example you have code from Usage section code that throws SocketTimeoutException

If you run it you will get stacktrace similar to this:

Exception in thread "main" java.net.SocketTimeoutException: Read timed out
	at java.base/java.net.SocketInputStream.socketRead0(Native Method)
	at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	...

As you can see, there is no way to understand from which line or class this request was started.

You should understand, this is not something unique for Kotlin coroutines or this adapter, you would have the same stacktrace with okhttp3.Callback if would throw an exception on failure To make this stacktrace more useful you can do a few things

Wrap exception manually:

suspend fun main() {
   try {
       client.newCall(request).await()
   } catch (e: IOException) {
       // Catch original exception
       // Use some logger that will write line number to logs, so you can find the source of exception
       someLogger.error(e)
       // or just wrap exception and throw it to get stacktrace
       throw IOException("Some additional debug info: ${e.message}", e)
   }
}

This will give you stacktrace that shows line where exception was rethrown or logged:

Exception in thread "main" java.io.IOException: java.net.SocketTimeoutException: Read timed out
    at ru.gildor.coroutines.okhttp.MainKt.main(main.kt:20)
    at ru.gildor.coroutines.okhttp.MainKt$main$1.invokeSuspend(main.kt)
...
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.base/java.net.SocketInputStream.socketRead0(Native Method)
    at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
...

Enable debug mode of kotlinx.coroutines:

// Set it before first usage of coroutines in your project
System.setProperty(DEBUG_PROPERTY_NAME, DEBUG_PROPERTY_VALUE_ON)

This will allow you to see line where request is started:

Exception in thread "main" java.net.SocketTimeoutException
    (Coroutine boundary)
    at ru.gildor.coroutines.okhttp.MainKt.main(main.kt:15)
Caused by: java.net.SocketTimeoutException: timeout
    at okio.Okio$4.newTimeoutException(Okio.java:230)
    at okio.AsyncTimeout.exit(AsyncTimeout.java:285)
...

This will give you coroutines stack so you can debug it in most cases

Enable stack recording

To help debug some complicated cases, when you want to know which code started coroutine, await() provides argument recordStack:

suspend fun main() {
    client.newCall(request).await(recordStack = true)
}

Instead of recovering coroutine stacktrace this call will create exception on method call to save stack and will throw it on error, so you will get detailed stack

Exception in thread "main" java.io.IOException
	at ru.gildor.coroutines.okhttp.MainKt.main(main.kt:15)
	...
Caused by: java.net.SocketTimeoutException: timeout
	at okio.Okio$4.newTimeoutException(Okio.java:230)
	...

By default stack recording is disabled, but you can enable it using system properties (should set it before first usage of the adapter):

System.setProperty(OKHTTP_STACK_RECORDER_PROPERTY, OKHTTP_STACK_RECORDER_ON)

But this method is relatively heavyweight because creates exception on each request (even successful, because we have to record stacktrace before invocation) and resulting stacktrace is full of coroutines internal calls,

So I recommend to use it only if you have hard times to understand what is caused the problem and you need all information




鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap