We’re seeing issues with withTokenManager. It doesn’t handle errors properly, especially in the logoutAndRevokeTokens function. Exceptions are not propagated correctly, and we’re running into issues like missing error_uri when calling the revokeRefreshToken method. (this is happening in production)
Our current solution is to not call logout on android devices.
Stack trace:
01-03 21:22:35.027 31480 31613 E AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
01-03 21:22:35.027 31480 31613 E AndroidRuntime: Process: io.montrose.mobile, PID: 31480
01-03 21:22:35.027 31480 31613 E AndroidRuntime: io.curity.haapi.react.FailedTokenManagerRequestException: Failed to make token request
01-03 21:22:35.027 31480 31613 E AndroidRuntime: Caused by: org.json.JSONException: No value for error_uri
Current Behavior:
- The exception is caught but not properly handled or propagated back.
- The event HaapiFinishedLoading isn’t always triggered.
Suggested Fixes:
withTokenManager: Use CompletableDeferred to ensure we handle the async result correctly. Complete it with an exception in case of failure, and always trigger HaapiFinishedLoading in finally. Please not that this should also apply to withHaapiManager
@Throws(FailedTokenManagerRequestException::class)
private fun withTokenManager(
onSuccess: ((TokenResponse) -> Unit)? = null,
accessorRequest: suspend (tokenManager: OAuthTokenManager, coroutineContext: CoroutineContext) -> TokenResponse?
) {
_eventEmitter.sendEvent(HaapiLoading)
val manager = _accessorRepository?.accessor?.oAuthTokenManager ?: throw notInitialized()
val result = CompletableDeferred<Unit>()
_haapiScope.launch {
try {
val response = accessorRequest(manager, this.coroutineContext)
if (onSuccess != null && response != null) {
onSuccess(response)
}
result.complete(Unit)
} catch (e: Exception) {
Log.w(TAG, "Failed to make token request: ${e.message}")
_eventEmitter.sendEvent(EventType.HaapiFinishedLoading)
result.completeExceptionally(FailedTokenManagerRequestException("Failed to make token request", e))
} finally {
_eventEmitter.sendEvent(EventType.HaapiFinishedLoading)
}
}
try {
result.await()
} catch (e: FailedTokenManagerRequestException) {
throw e
}
}
- logout: Reject the promise with a more detailed error message, so that the React Native side properly handles errors.
@ReactMethod
fun logout(promise: Promise) {
Log.d(TAG, "Logout was called, revoking tokens")
try {
if (_tokenResponse != null) {
_handler.logoutAndRevokeTokens(_tokenResponse!!.accessToken, _tokenResponse!!.refreshToken)
} else {
_handler.closeHaapiConnection()
}
_tokenResponse = null
resolveRequest(LoggedOut, "{}", promise)
} catch (e: Exception) {
Log.e(TAG, "Failed to logout: ${e.message}")
rejectRequest("Logout failed", e.message ?: "Unknown error", promise)
}
}
We’re seeing issues with withTokenManager. It doesn’t handle errors properly, especially in the logoutAndRevokeTokens function. Exceptions are not propagated correctly, and we’re running into issues like missing error_uri when calling the revokeRefreshToken method. (this is happening in production)
Our current solution is to not call logout on android devices.
Stack trace:
01-03 21:22:35.027 31480 31613 E AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1 01-03 21:22:35.027 31480 31613 E AndroidRuntime: Process: io.montrose.mobile, PID: 31480 01-03 21:22:35.027 31480 31613 E AndroidRuntime: io.curity.haapi.react.FailedTokenManagerRequestException: Failed to make token request 01-03 21:22:35.027 31480 31613 E AndroidRuntime: Caused by: org.json.JSONException: No value for error_uriCurrent Behavior:
Suggested Fixes:
withTokenManager: UseCompletableDeferredto ensure we handle the async result correctly. Complete it with an exception in case of failure, and always triggerHaapiFinishedLoadinginfinally. Please not that this should also apply to withHaapiManager