I'm using retrofit and eithernet and I'm trying to...
# squarelibraries
c
I'm using retrofit and eithernet and I'm trying to get the functionality that is listed in eithernets docs my server 200 with this for success
Copy code
{ "status: "success",  "data": {  } }
and 200 for failures
Copy code
{
  "status": "error",
  "message": "Please try again."
}
I can't seem to figure out the syntax needed for this converter factory (code in thread)🧵
I'm grabbing the converter factory from eithernets readme
Copy code
class ErrorConverterFactory : Converter.Factory() {
  override fun responseBodyConverter(
    type: Type,
    annotations: Array<out Annotation>,
    retrofit: Retrofit
  ): Converter<ResponseBody, *>? {
    val (errorType, nextAnnotations) = annotations.errorType() ?: return null
    return ResponseBodyConverter(errorType.toType())
  }

  class ResponseBodyConverter(
    private val errorType: Type
  ) : Converter<ResponseBody, *> {
    override fun convert(value: ResponseBody): String {
      if (value.string().contains("error")) { // todo: only inspect "status" property
        val errorResponse = MyErrorType("asd")
        throw ApiException(errorResponse)
      } else {
        return //how do i delegate to the regular Success type?
      }
    }
  }
}
FWIW. these are my success and error types
Copy code
data class SuccessResponse<T>(val status: String, val data: T)
data class FailureResponse(val status: String, val message: String)
Along with the retrofit declaration
Copy code
@DecodeErrorBody
@GET("/test2")
suspend fun test1(): ApiResult<SuccessResponse<Test1Response>, FailureResponse>

@DecodeErrorBody
@GET("/test1")
suspend fun test2(): ApiResult<SuccessResponse<Test2Response>, FailureResponse>
j
all 4xx are sent as 2xx?
c
400s can still happen... i suppose? (like a 401 or 403) but if the response is handled by our backend, then we 200. kinda as per jessewilsons one talk where he said doing this allows you to easily find out if an error is a result of a middlebox.
j
the 4xx marked as 2xx are deterministic?
c
let me follow up with my BE team. I think for now I could probably say that all errors will be 200s instead
j
I don't know how EitherNet works internally, in one library I have I am using
Copy code
internal fun <F : Any, S : Any> handleSuspend(
    call: NetworkEitherSuspendCall<F, S>,
    callback: Callback<NetworkEither<F, S>>,
    code: Int,
    body: S?,
    errorBody: F?,
    headers: Headers,
) =
    with(callback) {
        when (code) {
            in 200..299 -> {
                if (body != null) onResponse(call, Response.success(NetworkEither.success(body, code, headers)))
                else handleNullBody(callback, call, code, headers)
            }
            in 400..599 -> {
                if (errorBody != null) onResponse(call, Response.success(NetworkEither.httpFailure(errorBody, code, headers)))
                else handleNullErrorBody(callback, call)
            }
        }
    }
Everything is sent as
Response.success
, but you can use your custom
Either
, in my
NetworkEither.success
or
NetworkEither.httpFailure
, based on the status code
c
Yeah, I'm just trying to pull from eithernets readme which has an example directly for this case, but i kinda dont get the syntax of it all. like. idk where this error comes from. lol
j
I am not sure, I haven't used that library and in my case I am not using projections, I am using generics
Converter<ResponseBody, F>
c
lol. looks like i asked this question here https://github.com/slackhq/EitherNet/discussions/46 but wasn't able to get a response
j
@Zac Sweers ☝️ can you help? Several people including me can't figure out how to interpret the snippet at https://github.com/slackhq/EitherNet?tab=readme-ov-file#plugability
j
If your serialization library supports sealed classes or interfaces you can build your polymorphic error or success models
z
Hi, y'all should consider reading tests if you're confused, as they have an implementation of the README example.
It's pretty basic - peek at the body in an intermediate response body converter. you have to define what you're looking for, such as a
status
key or whatever you want, and then either proceed along the happy path if it's ok or throw an
ApiException
. That'll get caught and passed on to a converter for whatever error type you defined on the ApiResult.
In general, I don't think it's super polite to start summoning people in threads on a weekend like this. No one said what they tried, it's just two of you (not "several people") saying "I don't understand". It sounds like one or both of you didn't understand how to peek at a response body like the example does, and it would be a good exercise for the reader to maybe learn how to do that.
j
Didn't read this up until now. > In general, I don't think it's super polite to start summoning people in threads on a weekend like this. No one said what they tried, it's just two of you (not "several people") saying "I don't understand". It sounds like one or both of you didn't understand how to peek at a response body like the example does, and it would be a good exercise for the reader to maybe learn how to do that. Didn't think you'd have notifications enabled but I see your point: the burden of whether to mention someone or not falls on the sender side and not the other way around (I just wish the rest of the world thought the same). I am sorry I have not been mindful enough of others (you in this case). As for the usage of "several", I get I'm not a native speaker though the dictionary (at least the Mac's built-in dictionary) says "more than two but not many" and indeed it's at least three people including me and the people in these 2 discussions: https://github.com/slackhq/EitherNet/discussions/65 https://github.com/slackhq/EitherNet/discussions/46 But I'd appreciate you could let me know if you still think the usage of the term was inappropriate. Besides that, looking at the tests in the code (which is an option my mind completely disregarded 😞 ) was the right thing to do to get the bits I was missing. Thank you.
👍 1
c
Thanks for finding a solution Marco and thanks for the pointers Zac!