https://kotlinlang.org logo
Title
c

Colton Idle

03/31/2023, 4:56 AM
Do any of my super simple interceptors look wrong? Getting a crash of
Too many follow-up requests: 21
(full stacktrace in thread, stacktrace mentions both of these interceptors) interceptor 1
class AddOutboundAcceptHeaderInterceptor @Inject constructor() : Interceptor {
  override fun intercept(chain: Interceptor.Chain): Response {
    val request = chain.request().newBuilder().addHeader("Accept", "application/json").build()
    return chain.proceed(request)
  }
}
interceptor 2
class AddOutboundBasicAuthHeaderInterceptor
@Inject
constructor(private val buildTimeValues: BuildTimeValues) : Interceptor {
  override fun intercept(chain: Interceptor.Chain): Response {
    val auth = "Basic ${buildTimeValues.basicAuth.encodeUtf8().base64()}"
    val request = chain.request().newBuilder().addHeader("Authorization", auth).build()
    return chain.proceed(request)
  }
}
Full stacktrace
Fatal Exception: java.net.ProtocolException: Too many follow-up requests: 21
       at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:283)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:132)
       at com.rollertoaster.app.hilt.AddOutboundBasicAuthHeaderInterceptor.intercept(AddOutboundBasicAuthHeaderInterceptor.java:111)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:132)
       at com.rollertoaster.app.misc.AddOutboundAcceptHeaderInterceptor.intercept(AddOutboundAcceptHeaderInterceptor.java:85)
       at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:132)
       at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.java:100)
       at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.java:110)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
       at java.lang.Thread.run(Thread.java:923)
y

yschimke

03/31/2023, 5:29 AM
They look fine but generally this might be a server misconfiguration. Say bouncing you between two endpoints with redirect loop. Should be trivial to debug with an event listener or logging interceptor.
c

Colton Idle

03/31/2023, 5:40 AM
I only see this happening in production, so I guess a logging interceptor setup as a network interceptor is what I'd want to do?
I wonder how best to even setup a logging interceptor in production though. i dont want to log everything from every user. hrmm
y

yschimke

03/31/2023, 6:29 AM
I think you'll still have a priorResponse chain. So you could have an interceptor that prints that above a certain level or or a failure.
Probably worth reproducing locally deliberately and seeing the logging before pushing to prod.
c

Colton Idle

03/31/2023, 6:34 AM
Yeah, I guess that's my issue. Don't know how to repro locally. I've got some ideas. Thanks Yuri!
@yschimke i was looking on SO and github. Some people say it could be due to me using
addHeader
instead of
header
. Does that seem problematic to you?
y

yschimke

03/31/2023, 8:22 PM
If it's already got a bad header, and you are adding a second, then yes
It's hard to tell from just these interceptors.
c

Colton Idle

03/31/2023, 8:39 PM
Forgive my lack of knowledge here. What's a "bad header"?
y

yschimke

03/31/2023, 8:40 PM
An invalid Auth token, expired?
.header(...) Replaces. .addHeader(...) Adds an additional one
c

Colton Idle

03/31/2023, 8:41 PM
ooh.
so interceptor 1 and interceptor 2 and never be "wrong". but we have another interceptor that adds Auth (on top of basic http auth).
y

yschimke

03/31/2023, 8:41 PM
Rather than guessing. Use event listener or logging interceptors to print this out.
c

Colton Idle

03/31/2023, 8:42 PM
So I wonder if our third interceptor ends up calling these interceptors again.
y

yschimke

03/31/2023, 8:43 PM
It's not easy to debug these theoreticals on slack. Add logging or make a reproduction.
c

Colton Idle

03/31/2023, 8:44 PM
totally agree. just trying to understand a bit more because ive started adding logging to a prod release and now i just have a ton of logs and dont actually know what im looking for. lol
alright. i think i was able to repro a bad token refresh flow that gets in a loop. It doesn't actually cause a crash though, so I'm still lost there. BUT I did verify that my auth headers that get added above will NOT get added repeatedly for each subsequent request. so thats good.