Skip to content

Commit

Permalink
handle IO exceptions correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamVe committed Sep 10, 2024
1 parent a6038ca commit 827c95f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ class FidoConnectionHelper(private val deviceManager: DeviceManager) {
return requestHandled
}

fun failPending(e: Exception) {
pendingAction?.let { action ->
logger.error("Failing pending action with {}", e.message)
action.invoke(Result.failure(e))
pendingAction = null
}
}

fun cancelPending() {
pendingAction?.let { action ->
action.invoke(Result.failure(CancellationException()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,13 @@ class FidoManager(
// something went wrong, try to get DeviceInfo from any available connection type
logger.error("Failure when processing YubiKey: ", e)

// Clear any cached FIDO state
fidoViewModel.clearSessionState()
connectionHelper.failPending(e)

if (e !is IOException) {
// we don't clear the session on IOExceptions so that the session is ready for
// a possible re-run of a failed action.
fidoViewModel.clearSessionState()
}
throw e
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,15 @@ class OathManager(
)
)
if (!session.isLocked) {
oathViewModel.updateCredentials(calculateOathCodes(session))
try {
oathViewModel.updateCredentials(calculateOathCodes(session))
} catch (e: IOException) {
// in this situation we clear the session because otherwise
// the credential list would be in loading state
// clearing the session will prompt the user to try again
oathViewModel.clearSession()
throw e
}
}

// Awaiting an action for a different or no device?
Expand Down Expand Up @@ -315,14 +323,19 @@ class OathManager(
}
} catch (e: Exception) {
// OATH not enabled/supported, try to get DeviceInfo over other USB interfaces
logger.error("Failed to connect to CCID: ", e)
// Clear any cached OATH state
oathViewModel.clearSession()
logger.error("Exception during SmartCard connection/OATH session creation: ", e)

// Remove any pending action
pendingAction?.let { action ->
logger.error("Cancelling pending action")
logger.error("Failing pending action with {}", e.message)
action.invoke(Result.failure(e))
pendingAction = null
action.invoke(Result.failure(CancellationException()))
}

if (e !is IOException) {
// we don't clear the session on IOExceptions so that the session is ready for
// a possible re-run of a failed action.
oathViewModel.clearSession()
}

throw e
Expand Down
3 changes: 2 additions & 1 deletion lib/app/views/main_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class MainPage extends ConsumerWidget {
ref.listen<AsyncValue<YubiKeyData>>(currentDeviceDataProvider,
(prev, next) {
final serial = next.value?.info.serial;
if (serial != null && serial == prev?.value?.info.serial) {
if ((serial != null && serial == prev?.value?.info.serial) ||
(next.hasValue && (prev != null && prev.isLoading))) {
return;
}

Expand Down

0 comments on commit 827c95f

Please sign in to comment.