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.
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
}
}
}