ForgeRock Developer Experience

Error handling

When an error occurs during the registration or authentication process, the iOS SDK returns the following error. In most cases, errors are returned as per the specification:

public enum WebAuthnError: FRError {
    case badData
    case badOperation
    case invalidState
    case constraint
    case cancelled
    case timeout
    case notAllowed
    case unsupported
    case unknown
}

Error handling with AM node outcome

When you use WebAuthnRegistrationCallback.register() or WebAuthnAuthenticationCallback.authenticate(), the SDK automatically parses the error into the appropriate format for AM. When AM receives the node, the authentication flow follows the WebAuthn registration process to reach the appropriate outcome.

However, if the error has to be handled manually, the WebAuthnError provides a convenience method called WebAuthnError.convertToWebAuthnOutcome() to convert the error into an appropriate format.

WebAuthnError.unsupported results in Unsupported outcome in both the WebAuthn Registration and WebAuthn Authentication nodes.

Any other WebAuthnError results in a Client Error outcome in the nodes.

// keep HiddenValueCallback to set the value later
let hiddenValueCallback = HiddenValueCallback
if let registrationCallback = callback as? WebAuthnRegistrationCallback {
    //  Perform registration
    registrationCallback.register { (attestation) in
        // Registration successful

        // only if HiddenValueCallback is designated for WebAuthn outcome
        if hiddenValueCallback.isWebAuthnOutcome {
            // set attestation manually
            hiddenValueCallback.setValue(attestation)
        }
        // Submit the Node using Node.next()
    } onError: { (error) in
        // only if HiddenValueCallback is designated for WebAuthn outcome
        // and, the error is WebAuthnError
        if hiddenValue.isWebAuthnOutcome, let webAuthnError = error as? WebAuthnError {
            // set error outcome manually
            hiddenValueCallback.setValue(webAuthnError.convertToWebAuthnOutcome())
        }
        // Submit the Node using Node.next()
    }
}