renewAuth returns invalid_grant and sets status code to 0 on 403 HttpResponse

I’m working on an Android app and getting an unexpected response from the renewAuth API call when I try to refresh a token. The process works fine up until the token gets invalidated on the back-end. When I get a response with the http response code 403 Forbidden with body:

{“error”:“invalid_grant”,“error_description”:“Unknown or invalid refresh token.”}

what I want to do is check the callback and I expect that the error object will have the statusCode set to 403 to match the http response status code, but the value it holds is 0:

  • error = {AuthenticationException@20307} “com.auth0.android.authentication.AuthenticationException: An error occurred when trying to authenticate with the server.”
  • code = “invalid_grant”
  • description = “Unknown or invalid refresh token.”
  • statusCode = 0
  • values = {HashMap@20320} size = 2
  • 0 = {HashMap$Node@20348} “error” → “invalid_grant”
  • 1 = {HashMap$Node@20349} “error_description” → “Unknown or invalid refresh token.”
  • backtrace = {Object[11]@20321}
  • cause = {AuthenticationException@20307} “com.auth0.android.authentication.AuthenticationException: An error occurred when trying to authenticate with the server.”

How do I properly handle the response? Currently, I’m implementing the handling like this:

        authClient.renewAuth(profileService.getRefreshToken())
                .start(object : BaseCallback<Credentials, AuthenticationException> {
                    override fun onSuccess(payload: Credentials?) {
                        payload?.accessToken?.let { token ->
                            profileService.updateAuthToken(token)
                        }
                        payload?.refreshToken?.let { token ->
                            profileService.updateRefreshToken(token)
                        }
                        customerModel.getCustomerProfile()
                        it.onSuccess(true)
                    }

                    override fun onFailure(error: AuthenticationException?) {
                        // return false if we get a 403 or a 401...
                        if (error?.statusCode == CODE_ERROR_FORBIDDEN || error?.statusCode == CODE_ERROR_UNAUTHORIZED) {
                            if (!BuildConfig.DEBUG) {
                                NewRelic.recordHandledException(error)
                            }
                            Log.e(this::class.tag, "Error code = ${error.code}, description = ${error.description}")
                            it.onSuccess(false)
                        } else {
                            // ... or accessDenied, otherwise, we don't want to clear the token
                            it.onSuccess(error?.isAccessDenied != true)
                        }
                    }
                })

but as noted above, the statusCode in the error object (AuthenticationException) has a value of 0. The java docs do indicate that it can have a value of 0 “if not set”, but it seems contrary not to have it set to the http status code. Seems like if it can be “not set” then you can’t really rely on it.

How do I handle a 403 (or 401) response on a renewAuth call if the value isn’t getting propagated to the error object?

Thanks,
Dan Costinett

Hey there!

Sorry for such huge delay in response! We’re doing our best in providing you with best developer support experience out there, but sometimes our bandwidth is not enough comparing to the number of incoming questions.

Wanted to reach out to know if you still require further assistance?