From 8f3b75a5b0deae3604ee8706a180e55130d52912 Mon Sep 17 00:00:00 2001 From: Abhash Kumar Singh Date: Mon, 1 Jul 2024 14:27:27 -0700 Subject: [PATCH] chore: handle decoding errors --- .../HostApp/Views/ExampleLivenessView.swift | 2 ++ .../Liveness/FaceLivenessDetectionError.swift | 6 ++++++ .../Liveness/FaceLivenessDetectionView.swift | 21 ++++++++++++++++--- .../FaceLivenessDetectionViewModel.swift | 5 +++++ .../Views/Liveness/LivenessStateMachine.swift | 1 + 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/HostApp/HostApp/Views/ExampleLivenessView.swift b/HostApp/HostApp/Views/ExampleLivenessView.swift index 39407c89..5773d426 100644 --- a/HostApp/HostApp/Views/ExampleLivenessView.swift +++ b/HostApp/HostApp/Views/ExampleLivenessView.swift @@ -45,6 +45,8 @@ struct ExampleLivenessView: View { viewModel.presentationState = .error(.countdownFaceTooClose) case .failure(.invalidSignature): viewModel.presentationState = .error(.invalidSignature) + case .failure(.runtimeError): + viewModel.presentationState = .error(.runtimeError) default: viewModel.presentationState = .liveness } diff --git a/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionError.swift b/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionError.swift index a19cfd57..8de9bd22 100644 --- a/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionError.swift +++ b/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionError.swift @@ -125,6 +125,12 @@ public struct FaceLivenessDetectionError: Error, Equatable { message: "The signature on the request is invalid.", recoverySuggestion: "Ensure the device time is correct and try again." ) + + public static let runtimeError = FaceLivenessDetectionError( + code: 18, + message: "An unexpected runtime error occurred.", + recoverySuggestion: "Please try again." + ) public static func == (lhs: FaceLivenessDetectionError, rhs: FaceLivenessDetectionError) -> Bool { lhs.code == rhs.code diff --git a/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionView.swift b/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionView.swift index f31d2390..63b23e68 100644 --- a/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionView.swift +++ b/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionView.swift @@ -82,8 +82,6 @@ public struct FaceLivenessDetectorView: View { isPreviewScreenEnabled: !disableStartView ) ) - - faceDetector.setFaceDetectionSessionConfigurationWrapper(configuration: viewModel) } init( @@ -143,6 +141,22 @@ public struct FaceLivenessDetectorView: View { throw FaceLivenessDetectionError.accessDenied } } + DispatchQueue.main.async { + if let faceDetector = viewModel.faceDetector as? FaceDetectorShortRange.Model { + faceDetector.setFaceDetectionSessionConfigurationWrapper(configuration: viewModel) + } + } + } + .onReceive(viewModel.$livenessState) { output in + switch output.state { + case .encounteredUnrecoverableError(let error): + let closeCode = error.webSocketCloseCode ?? .normalClosure + viewModel.livenessService?.closeSocket(with: closeCode) + isPresented = false + onCompletion(.failure(mapError(error))) + default: + break + } } case .awaitingLivenessSession(let challenge): Color.clear @@ -157,7 +171,6 @@ public struct FaceLivenessDetectorView: View { } } } - case .displayingGetReadyView(let challenge): GetReadyPageView( onBegin: { @@ -219,6 +232,8 @@ public struct FaceLivenessDetectorView: View { return .faceInOvalMatchExceededTimeLimitError case .socketClosed: return .socketClosed + case .runtimeError: + return .runtimeError default: return .cameraPermissionDenied } diff --git a/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionViewModel.swift b/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionViewModel.swift index e83c7c22..1c61bae4 100644 --- a/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionViewModel.swift +++ b/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionViewModel.swift @@ -111,6 +111,11 @@ class FaceLivenessDetectionViewModel: ObservableObject { self?.livenessState .unrecoverableStateEncountered(.socketClosed) } + case .runtimeError: + DispatchQueue.main.async { + self?.livenessState + .unrecoverableStateEncountered(.runtimeError) + } } }) diff --git a/Sources/FaceLiveness/Views/Liveness/LivenessStateMachine.swift b/Sources/FaceLiveness/Views/Liveness/LivenessStateMachine.swift index fa66ffb0..efad73de 100644 --- a/Sources/FaceLiveness/Views/Liveness/LivenessStateMachine.swift +++ b/Sources/FaceLiveness/Views/Liveness/LivenessStateMachine.swift @@ -164,6 +164,7 @@ struct LivenessStateMachine { static let timedOut = LivenessError(code: 4, webSocketCloseCode: .ovalFitMatchTimeout) static let couldNotOpenStream = LivenessError(code: 5, webSocketCloseCode: .unexpectedRuntimeError) static let socketClosed = LivenessError(code: 6, webSocketCloseCode: .normalClosure) + static let runtimeError = LivenessError(code: 7, webSocketCloseCode: .unexpectedRuntimeError) static let viewResignation = LivenessError(code: 8, webSocketCloseCode: .viewClosure) static func == (lhs: LivenessError, rhs: LivenessError) -> Bool {