Documentation Hub
Mobile SDK
Mobile SDK
  • Keyless SDK Documentation
  • Introduction
    • 🧩Components
    • ⚙️Integration Flows
    • 🤳Sample Apps
  • 📱Mobile SDK Guide
    • 1️⃣ Getting started
    • 2️⃣ Enrollment
    • 3️⃣ Authentication
    • 4️⃣ De-Enrollment
    • 5️⃣ Backup
    • 6️⃣ User and device management
  • 📱Mobile SDK Reference
    • UI Customization
    • Error handling
    • Liveness Settings
    • JWT signing
    • PIN authentication
    • Introduce Keyless to Users
  • 📱Mobile SDK Use Cases
    • Account recovery
    • Dynamic Linking
  • 📒Mobile SDK Changelog
    • Changelog
  • 💽Server API
    • Getting Started
    • Users
    • Devices
    • Operations
Powered by GitBook
On this page
  • Internal errors
  • Integration errors
  • User errors
  • Examples

Was this helpful?

  1. Mobile SDK Reference

Error handling

The Keyless SDK uses three classes of errors, each error has an error code and an error message. Errors follow 3 main categories:

  • Internal errors: triggered by Keyless internals.

  • Integration errors: triggered by a KeylessSDK integration misconfiguration.

  • User errors: triggered by unintended user behavior.

If you're implementing the Keyless SDK, you should handle errors coming from the SDK since the error message is not intended for end users.

Internal errors

Internal errors have code that are lower than 20_000. Internal errors require investigation from Keyless. If errors persist, please keep the error code, error message and stacktrace and contact us.

Integration errors

Integration errors have codes that span from 20_000 to 30_000. Integration errors can be solved by making sure you are not misusing the API surface of the SDK. You can solve it by reading the error message and addressing the issue. If errors persist, please keep the error code, error message and stacktrace and contact us.

User errors

Note that many of these errors are predictions only, when writing messages for your users it's often best to assume positive intent. For example, suggest that they make sure that nothing is obstructing the camera instead of suggesting that they are attempting to spoof.

User errors have code that are higher than 30_000.

Error
Code
Description

Spoofing

30000

The user might be placing a picture or a video in front of the camera.

Timeout

30001

The face could not be recognized before the specified timed out.

Mask detected

30002

The user might be wearing a mask, or there might be something hiding their face. Note: mask detected will be part of live feedback and no longer returned as an error from SDK version 4.8.0 and above.

User cancelled

30003

The user manually cancelled the face recognition and processing.

Face not matching

30004

The face of user in front of the camera does not match the face currently enrolled with Keyless.

No network connection

30005

The device appears to be offline.

Device tampered

30006

The device seems tampered and could have been rooted or jailbroken.

User lockout

30007

The user is temporarily locked out of Keyless after too many failed authentication attempts.

Rejected

30008

Keyless did not manage to recognize the user but does not suspect any spoofing attempt.

Camera denied

30009

The user denied camera permission.

Examples

val configuration = Keyless.AuthenticationConfiguration()

Keyless.authenticate(
    authenticationConfiguration = configuration,
    onCompletion = { result ->
        when (result) {
            is Keyless.KeylessResult.Success -> {
                Log.d("IntegratorActivity ", "Authenticate success")
            }
            is Keyless.KeylessResult.Failure -> {
                when (result.error) {
                    is KeylessUserError.FaceNotMatching -> Log.d("IntegratorActivity ", "Face not matching")
                    is KeylessUserError.MaskDetected -> Log.d("IntegratorActivity ", "Mask detected")
                    is KeylessUserError.Spoofing -> Log.d("IntegratorActivity ", "Spoofing detected")
                    is KeylessUserError.Timeout -> Log.d("IntegratorActivity ", "The operation timed out")
                    is KeylessUserError.UserCancelled -> Log.d("IntegratorActivity ", "The user cancelled the operation")
                    is KeylessUserError.NoNetworkConnection -> Log.d("IntegratorActivity ", "No network connection available")
                    is KeylessUserError.Lockout -> Log.d("IntegratorActivity ", "Your account is temporarily locked")
                    else -> {
                        Log.d("IntegratorActivity ", "Authenticate failure")

                        val errorCode = result.error.code
                        val errorMessage = result.error.message
                        val errorCause = result.error.cause?.printStackTrace()
                        // here you could display a generic error popup with the error code
                    }
                }
            }
        }
    }
)
let configuration = Keyless.AuthenticationConfiguration.builder.build()

Keyless.authenticate(authenticationConfiguration: configuration) { result in
    switch result {
    case .success(let authenticationSuccess):
        print("authenticationDidFinish:  \(authenticationSuccess.token)")
    case .failure(let error):
        switch error.kind {
        case .userError(let userError):
            switch userError {
            case .faceNotMatching:
                print("Face not matching")
            case .maskDetected:
                print("Mask detected")
            case .spoofing:
                print("Spoofing detected")
            case .timeout:
                print("The operation timed out")
            case .userCancelled:
                print("The user cancelled the operation")
            case .noNetworkConnection:
                print("No network connection available")
            case .lockout:
                print("Your account is temporarily locked")
            }
        default:
            let code = error.code
            let message = error.message
            // here you could display a generic error popup with the error code
        }
    }
}
import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';

final configuration = BiomAuthConfig();

try {
  final result = await Keyless.instance.authenticate(configuration);
  print("Authentication successful");
} catch (error) {
  if (error is KeylessError) {
    switch (error.errorType) {
      case KeylessErrorType.user:
        if (error.code == KeylessErrorCase.faceNotMatching.code) {
          print("Face not matching");
        } else if (error.code == KeylessErrorCase.maskDetected.code) {
          print("Mask detected");
        } else if (error.code == KeylessErrorCase.spoofing.code) {
          print("Spoofing detected");
        } else if (error.code == KeylessErrorCase.timeout.code) {
          print("The operation timed out");
        } else if (error.code == KeylessErrorCase.userCancelled.code) {
          print("The user cancelled the operation");
        } else if (error.code == KeylessErrorCase.noNetworkConnection.code) {
          print("No network connection available");
        } else if (error.code == KeylessErrorCase.deviceTampered.code) {
          print("Device security check failed");
        } else if (error.code == KeylessErrorCase.lockout.code) {
          print("Your account is temporarily locked");
        }
        break;
      default:
        // Handle internal or integration errors
        print("Authentication failed: ${error.message} (Code: ${error.code})");
        // Here you could display a generic error popup with the error code
    }
  }
}

Last updated 29 days ago

Was this helpful?

📱