java.io.IOException when getting data from error response

1k Views Asked by At

I have implemented a simple POST request for login API.

val fuelRequest = Fuel.post(urlString)
    .header("Content-Type", "application/json")
    .header("Accept", "application/json")
    .jsonBody(UtilsString.getStringForDictionary(params))

fuelRequest.response() { _, response, result ->
    ...
    callback.onComplete(result)
}

When the response is ok, there is no problem. The problem occurs when I try to get the data response from an error request. The data that I get is this :

{
    "code": 401,
    "error": "The specified credentials are invalid."
}

And this comes with a 401 Unauthorised response. I've just wanted to get the message from de request. If I try response.data it throws Method threw 'java.io.IOException If I try result.component()2.response it throws Method threw 'android.os.NetworkOnMainThreadException' exception. Cannot evaluate com.github.kittinunf.fuel.core.Response.toString() If I try result.error.errorData it throws Method threw 'java.io.IOException

Any clue how can I get the response?

3

There are 3 best solutions below

0
J.P On BEST ANSWER

I couldn't add code snippet in the comment but here is the code snippet. You could take the request something like this and do whatever you want according to your usecase.

import com.github.kittinunf.fuel.Fuel
import com.github.kittinunf.fuel.core.FuelError
import com.github.kittinunf.result.Result

private class ResponseError(
        val statusCode: Int,
        val statusMessage: String,
        val errorMessage: String
) : RuntimeException("[%d - %s] %s".format(statusCode, statusMessage, errorMessage))

fun main(args: Array<String>) {

    val (request, response, result) = Fuel.post("http://httpbin.org/post").responseString()

    when (result) {
        is Result.Failure -> onError(result)
    }
    print("done")
}

/**
 *
 */
fun onError(failureResult: Result.Failure<String, FuelError>) {
    throw ResponseError(
            statusCode = failureResult.error.response.statusCode,
            statusMessage = failureResult.error.response.responseMessage,
            errorMessage = failureResult.getErrorMessage())
}

/**
 *
 */
private fun Result.Failure<String, FuelError>.getErrorMessage(): String {
    return try {
        val string = String(this.error.errorData)
        print(string)
        string
    } catch (e: RuntimeException) {
        ""
    }
}
0
J.P On

You could get the response like this and do whatever you want with the response.

Fuel.post("https://api.chui.ai/v1/enroll")
                            .header(headers)
                            .body(json.toString(), Charset.forName("UTF-8"))
                            .responseString(new com.github.kittinunf.fuel.core.Handler<String>() {

                            @Override
                            public void failure(@NotNull com.github.kittinunf.fuel.core.Request request,
                                                @NotNull com.github.kittinunf.fuel.core.Response response,
                                                @NotNull FuelError error) {
                                Log.d("Fuel.failure", error.getMessage());
                            }

                            @Override
                            public void success(@NotNull com.github.kittinunf.fuel.core.Request request,
                                                @NotNull com.github.kittinunf.fuel.core.Response response,
                                                String data) {
                                // data is a string, parse as using you fav json library
                                Log.d("Fuel.success", data);
                            }
1
mhlnstdt25 On

I copied your code and if I add this:

findViewById<FloatingActionButton>(R.id.fab).setOnClickListener { view ->
            val fuelRequest = Fuel.post("http://10.0.2.2:3000/")
                    .header("Content-Type", "application/json")
                    .header("Accept", "application/json")
                    .jsonBody(UtilsString.getStringForDictionary(params))

            fuelRequest.response() { _, response, _ ->
                println(String(response.data))
            }
}

I can see the body of the error response. The endpoint 10.0.2.2:3000 is a small express.js application which delivers just a small json.

app.post('/', function (req, res) {
  res.status(401).jsonp({ error: 'failed' })
});