-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Description
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:
- The exception is caught but not properly handled or propagated back.
- The event HaapiFinishedLoading isn’t always triggered.
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
@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)
}
}Metadata
Metadata
Assignees
Labels
No labels