Why when extending a type would I lose properties ...
# getting-started
m
Why when extending a type would I lose properties on it? This is my code:
Copy code
fun Response<*>.createError(): Error {
    val errorBody = this.errorBody() ?: run {
        logger.error { "createError failed: null errorBody found" }
        throw ClassCastException("Null errorBody found on response")
    }

    val error = Gson().fromJson(errorBody.string(), models.Error::class.java)
    return error
}
What is happening is I am losing the contents of
errorBody
when I try to use the receiver (Response)... I've read over the docs on class extension and I don't see anything about this?
m
what do you mean by "losing the contents"?
m
Well, what happens is that before I call the extension function I can access the contents of
errorBody
just fine. Once I am in the scope of the extension function,
errorBody
no longer has the contents (a string)
m
so, you're getting the manually-thrown
ClassCastException
when you call
createError()
?
m
Nope. I enter the scope of createError() just fine, but once inside when I call
errorBody()
it is just an empty string
If it helps, Response is a type class belonging to the retrofit library
m
have you put a breakpoint in
createError()
and stepped into
errorBody()
to see what's happening?
m
I have not, I've just been using the debugger and looking at what it is showing me. I haven't actually stepped in.
Let me give that a shot
m
AFAIK your
createError()
function should be able to call
errorBody()
just fine -- if you are trying to call
errorBody()
multiple times, though, I don't know if there are any Retrofit-specific limitations that you're running into
m
That's the thing - I can call
errorBody()
fine, it's just that it loses any context that it had before it enters the scope of
createError()
Let me take a screenshot, that might help explain
m
my point is that your outside-of-scope
errorBody()
call might be consuming the content, such that by the time your second, inside-of-scope
errorBody()
call is made, the content is gone -- streaming APIs sometimes have destructive read behaviors like that
m
Before entering
createError()
After entering
createError()
Ohhhhh - okay, I see what you mean. That is interesting - I hadn't thought about the fact that it may consume it and then no longer be available!
m
I don't think I've ever tried calling
errorBody()
twice on the same
Response
, so I'm not sure what the behavior is supposed to be
but your screenshots feel like "content was consumed" more than "Kotlin extension functions are screwy" 😄
m
YUP!
You were spot on!
As soon as I removed my original logging function that DID call
errorBody()
it started working!
Wow, I've never encountered something like that before. I appreciate the help Mark!
m
you're welcome!
i