2

I am passing null right now, which causes a crash!

See: val response: Response<ReviewResponse> = Response.error(-1, null)

Code:

suspend fun getReviewData() = getResult {
        try {
            apiService.getReviewData(getCustomerId())
        } catch (e: Exception) {
            val response: Response<ReviewResponse> = Response.error(-1, null)
            response
        }
    }

   

As you can see null is not accepting internally, and I must need pass this: ResponseBody body

enter image description here

vvvvv
  • 25,404
  • 19
  • 49
  • 81

4 Answers4

3

What about this:

Response.error(404, ResponseBody.create(null, "Not found response body"))
Thommy
  • 5,070
  • 2
  • 28
  • 51
  • 4
    For those on Kotlin. There are extension functions defined so one can do `Response.error(404, "Not found".toResponseBody())`. – Ondrej Burkert Sep 22 '22 at 14:38
1

You can create a result data class like this

 data class ApiResult<out T>(
    val status: Status,
    val data: T?,
    val error: Throwable?,
    val message: String?
) {

    enum class Status {
        SUCCESS,
        ERROR,
        LOADING
    }

    companion object {
        fun <T> success(data: T?): ApiResult<T> {
            return ApiResult(Status.SUCCESS, data, null, null)
        }

        fun <T> error(message: String, error: Throwable?): ApiResult<T> {
            return ApiResult(Status.ERROR, null, error, message)
        }

        fun <T> loading(data: T? = null): ApiResult<T> {
            return ApiResult(Status.LOADING, data, null, null)
        }
    }

    override fun toString(): String {
        return "Result(status=$status, data=$data, error=$error, message=$message)"
    }
}

and then create your custom base response like this

 data class CommonResponse<T>(
    @SerializedName("error") val error: Boolean,
    @SerializedName("status") val status: Int,
    @SerializedName("message") val message: String?,
    @SerializedName("response") val response: T?
)

and assign them like this in retrofit

suspend fun <T> getResponse(
        request: suspend () -> Response<T>
    ): ApiResult<T> {
        return try {
            val result = request.invoke()
            if (result.isSuccessful) {
                return ApiResult.success(result.body())
            } else {

                ApiResult.error("Error", null)
            }
        } catch (e: Throwable) {
            ApiResult.error("Unkown Error", e)
        }
    }

and use them like this in call

interface CheckWhereApi {
    //Check Where API
    @GET("url")
    suspend fun checkWhere(): Response<CommonResponse<MyModel>>
}
Shogun Nassar
  • 606
  • 7
  • 16
0

Depend on your requirement addBody() function you are not passing any param here. need to pass param.

look like api construction in your code missing . please follow link to know more- https://www.chillcoding.com/android-retrofit-send-http/

++ update depend on your comment i think you not get direct answer , i am not give direct answer, its depend on exact architecture you following. little bit more info java.lang.IllegalArgumentException: code < 400: -1 its define architecture.

 if (code < 400) throw new IllegalArgumentException("code < 400: " + code);

here i suggest you how you going to return result its quite complicated , you try with some custom class with error handle and success handle.

data class ResponseByApi(val success: Any, val code: Int, val 
error : Any)

create response model class and set value as per network response like success set success body and code else if fail set error body and code -> return as per response.

RAMCODER
  • 61
  • 6
  • Hi, this link is not relevant. Reuqest you to please re-read and understand my question. See, If I've internet connection then everything is working fine, I'm able to rendered data to my UI in recyclerview and everything works fine. But If I turned off my internet connection and hit the api, then in interceptor I'm checking and if I don't hv connection then I'm throwing IOException, that comes to this class, where I'm catching the exception. But I need to return okhttp response to UI, even though it is dummy, because that getresult fun non null return value. So I created a dummy response but.. –  Mar 11 '22 at 08:24
  • ...that's not working. see my previouse question: https://stackoverflow.com/questions/71377479/how-to-stop-retrofit-okhttp-request-from-addnetworkinterceptor-only-and-should –  Mar 11 '22 at 08:25
  • In addBody() I'm not passing because I do not hv actual response. –  Mar 11 '22 at 08:25
  • please check updated comment @sychi Singh – RAMCODER Mar 11 '22 at 13:51
  • I'm think I'm not able to explain my problem properly. I know you're helping a lot. So I edited my question and also added one image. Maybe with that you'll get an idea. Please read entire question again. –  Mar 11 '22 at 18:03
  • yes i got your point you try to achieve okkhttp3 response object , that reason i told you not to use like that response structure in future also different code or body send you face issue . you can create custom response structure as return result as you expected to ui like how you handle okhttp3 response in your ui. – RAMCODER Mar 12 '22 at 08:03
0

I see that the code looks:

public static <T> Response<T> error(int code, ResponseBody body) {
    Objects.requireNonNull(body, "body == null");
    if (code < 400) throw new IllegalArgumentException("code < 400: " + code);
    return ... // build error response
}

And you call it:

val response: Response = Response.error(-1, null)

Thus, it will fail by NullPointerException.

Even if you comment on this line, it will fail by IllegalArgumentException because the code is less than 400.

However, you need to return Response<ReviewResponse> type.

You could use ResponseEntity for this:

new ResponseEntity<>(HttpStatus.OK);

It will be exactly creating dummy ResponseBody object which required by OkHttp. But you need to use ResponseEntity instead of Response.

Or you could throw exception, like:

throw new ResponseStatusException(
    HttpStatus.NOT_FOUND, "entity not found"
);

From org.springframework.web.server.ResponseStatusException

catch23
  • 17,519
  • 42
  • 144
  • 217