Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse Kotlin metadata manually to honor nullability and avoid kotlin-metadata-jvm dep #3075

Open
AidanLaing opened this issue Apr 12, 2019 · 30 comments

Comments

@AidanLaing
Copy link

Version: 2.6.0-SNAPSHOT
Exception: KotlinNullPointerException
Message: Response from {path to my suspend fun...} was null but response body type was declared as non-null

The current structure of my suspend fun in my service interface:

@POST("api/...")
suspend fun request(@Body body: Body): Response?

I'm using Gson for serialization.

Is there a way to declare the response body type as nullable that I'm missing? I've tried adding null safety on my response object with ? and @Nullable with no success.

@JakeWharton
Copy link
Collaborator

JakeWharton commented Apr 12, 2019 via email

@rodion-m

This comment has been minimized.

@JakeWharton

This comment has been minimized.

@JakeWharton JakeWharton changed the title Coroutines suspend fun 204 no content response throwing KotlinNullPointerException Parse Kotlin metadata manually to honor nullability and avoid kotlin-metadata-jvm dep Jun 5, 2019
@wlara

This comment has been minimized.

@JakeWharton

This comment has been minimized.

@Hospes
Copy link

Hospes commented Jul 3, 2019

Hi there! Any chance to get update on this issue? :) Want to move to 2.6.0 and remove all other dependencies but can't cause of null response body not supported :(

@jgavazzisp

This comment has been minimized.

@JakeWharton

This comment has been minimized.

@JavierSegoviaCordoba

This comment has been minimized.

@JakeWharton

This comment has been minimized.

@claucookie
Copy link

Just in case it helps. I was experiencing the exact same KotlinNPE issue over the last 2 days and after trying Converters and Adapters what really worked was to return Response<Unit> in the retrofit method declaration.

I use Retrofit 2.6.0.

@Pitel
Copy link

Pitel commented Dec 11, 2019

Any progress? We've just changed some of our REST endpoints to 204. So I thought it would be enought to just remove response type (making it Unit), but no.

Using Response<Unit> works 👍

@vladimirfx
Copy link

@JakeWharton
Copy link
Collaborator

Because it doesn't provide the necessary info

@september669
Copy link

september669 commented Feb 20, 2020

Using Response<Unit> works

In this case retrofit does not throw any exception when got 4xx codes
Reproduced at 2.6.2

@JakeWharton
Copy link
Collaborator

That is the expected behavior for that return type.

@MiSikora
Copy link

Is it something that is open for a PR or do you want to implement it yourself in Retrofit or as an external project and use it here? I see that there is an old branch so I'd like to ask first before spending some time on it.

@JakeWharton
Copy link
Collaborator

JakeWharton commented Feb 25, 2020 via email

@RoarGronmo
Copy link

Found that empty response failed with the NPE mentioned. To cope with that problem, I wrapped all my backend json calls (on the backend side) inside an array. So if the result was empty, I returned an empty array at least.

Just a tip to solve the problem if you have access and ability to change your backend data source.

RG

fbarthelery added a commit to fbarthelery/gradle-avdl that referenced this issue May 8, 2020
Retrofit doesn't support suspend function with nullable return Type
square/retrofit#3075
@jemshit
Copy link

jemshit commented Jul 3, 2020

Using Response<Unit> works

In this case retrofit does not throw any exception when got 4xx codes
Reproduced at 2.6.2

Hi, to handle empty response only choice seems like Response<Void> but that makes 4xx look like success.
Any proper way to handle both empty response AND see 4xx as error (e.g. @GET suspend fun should throw exception) ?

Update: Using custom response converter suggested in #1554 works fine, (not converting empty body and returning null in such cases). But return type in API interface must be Unit instead of Any?. Otherwise it throws exception written above by OP

davidasensio added a commit to davidasensio/TrackMap that referenced this issue Sep 4, 2020
davidasensio added a commit to davidasensio/TrackMap that referenced this issue Sep 4, 2020
@magneticflux-
Copy link

#3075 (comment)

Why not:

https://github.com/Kotlin/kotlinx.reflect.lite

#3075 (comment)

Because it doesn't provide the necessary info

Are you sure? It looks to me like you can read "one isNullable boolean" right here: https://github.com/Kotlin/kotlinx.reflect.lite/blob/47bfb95540f361143add39300017c6904720812a/src/main/java/kotlinx/reflect/lite/api.kt#L45-L47

@klaszlo8207
Copy link

Any new on this?

How to handle 400 codes and empty body?
I tried everything in this topic, but nothing worked.

Success called with the 400 error

@GiridharaSPK
Copy link

I have added wrong headers that caused me that HTTP 400 Bad request error.

removing the following worked
.addHeader("Content-Encoding", "UTF-8")
.header("Accept-Encoding", "identity")

  might help someone

@rezznov
Copy link

rezznov commented Mar 9, 2021

@JakeWharton not any updates about this? Its been 2 years since issue has open :D

@rezznov
Copy link

rezznov commented Mar 9, 2021

right now I handled this by a simple try catch like this

try {
                ResultWrapper.Success(request.invoke())
            } catch (e: KotlinNullPointerException) {
                ResultWrapper.NoContentError
            }

@LouisCAD
Copy link

LouisCAD commented Mar 9, 2021

Having an interceptor that rewrites the http 204 and 205 responses to 200 should work best.

@ferinagy
Copy link

Hi, I hit this a few times recently, so I thought I'd give it a shot: #3544. Any feedback is welcome.

@Snailedlt
Copy link

If you get No type arguments expected for class Response when using Response<Unit>, make sure you're using retrofit2.Response<> and not something like okhttp3.Response. That fixed the issue for me

@tamimattafi
Copy link

If you get No type arguments expected for class Response when using Response<Unit>, make sure you're using retrofit2.Response<> and not something like okhttp3.Response. That fixed the issue for me

This saved me a lot of digging, was using a Response<T> class from my module

@MoustafaElsaghier
Copy link

any suggestion for flow?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests