Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate WebAuthenticationExceptions caused by a user cancelling the flow into a single exception. #395

Open
5 tasks done
danallen88 opened this issue Jan 10, 2024 · 1 comment
Labels
android feature request A feature has been asked for or suggested by the community ios

Comments

@danallen88
Copy link

danallen88 commented Jan 10, 2024

Checklist

  • I have looked into the Readme, Examples, and FAQ and have not found a suitable solution or answer.
  • I have looked into the API documentation and have not found a suitable solution or answer.
  • I have searched the issues and have not found a suitable solution or answer.
  • I have searched the Auth0 Community forums and have not found a suitable solution or answer.
  • I agree to the terms within the Auth0 Code of Conduct.

Describe the problem you'd like to have solved

Users cancelling a web authentication session workflow results in a WebAuthenticationException with an internal code field that describes the cause for the exception. Presumably this is because many things could cause this type of exception.

I have a use case where knowing specifically that the user cancelled the session is helpful, but in order to identify whether this action was taken by a user, I must inspect the code for each platform that can throw it (iOS and Android for me) and determine whether the code is either USER_CANCELLED (iOS) or a0.authentication_canceled (Android). These appear to be platform-specific codes that are emitted from a native layer.

Describe the ideal solution

Ideally there is an exception type that wraps any scenario where a user cancelled the web authentication session, perhaps by subclassing WebAuthenticationException with a new exception UserCancelledWebAuthenticationException. Internal to the SDK, this exception can be created by inspecting the variety of codes that indicate the exception, and create a single exception that could be caught and dealt with.

Alternatives and current workarounds

As it stands, this is the class I am using to capture these codes:

import 'package:auth0_flutter/auth0_flutter.dart'
    show WebAuthentication, WebAuthenticationException;

/// {@template web_authentication_exception_code}
/// Error codes that can be returned from a [WebAuthentication] session within a
/// [WebAuthenticationException].
///
/// These codes are emitted from the native layer which means that different
/// unique codes can exist for the same type of exception on different
/// platforms.
/// {@endtemplate}
enum WebAuthenticationExceptionCode {
  /// The user cancelled an iOS web authentication session.
  iOSUserCancelled('USER_CANCELLED'),

  /// The user cancelled an Android web authentication session.
  androidUserCancelled('a0.authentication_canceled');

  /// {@macro web_authentication_exception_code}
  const WebAuthenticationExceptionCode(this.code);

  /// The [String]-based code representing the reason for the exception.
  final String code;

  /// Whether the given [code] represents a user cancelling a web authentication
  /// session regardless of platform.
  static bool userCancelled(String code) =>
      code == WebAuthenticationExceptionCode.iOSUserCancelled.code ||
      code == WebAuthenticationExceptionCode.androidUserCancelled.code;
}

Then in my login method I am doing something like the following:

try {
      return await _auth0
          .webAuthentication(scheme: _customScheme)
          .login(audience: _audience);
    } on WebAuthenticationException catch (error, stackTrace) {
      if (WebAuthenticationExceptionCode.userCancelled(error.code)) {
        Error.throwWithStackTrace(
          LoginCancelledException(error),
          stackTrace,
        );
      }

      rethrow;
    } catch (error, stackTrace) {
      Error.throwWithStackTrace(
        LoginException(error),
        stackTrace,
      );
    }

Additional context

No response

@danallen88 danallen88 added the feature request A feature has been asked for or suggested by the community label Jan 10, 2024
@MilesAdamson
Copy link

I have the exact same thing in my app

      if (e.code == "USER_CANCELLED" ||
          e.code == "a0.authentication_canceled") {
        // user closed the login webpage
        store.dispatch(const LoginFailedAction("Login cancelled"));
        return;
      }

There are differences when tokens fail to refresh while offline as well. The android "code" is not even really a code, it's a full sentence (same as the message).

  static const _androidRefreshErrorCode =
      "An error occurred while trying to use the Refresh Token to renew the Credentials.";
  static const _iOSRefreshErrorCode = "RENEW_FAILED";

It would be very nice to have the codes be identical on all platforms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android feature request A feature has been asked for or suggested by the community ios
Projects
None yet
Development

No branches or pull requests

3 participants