Giter VIP home page Giter VIP logo

kotlin-coroutines-okhttp's 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

kotlin-coroutines-okhttp's People

Contributors

gildor avatar romrell4 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.