From ee7e180684dbc6af7531480712c15b569d02052a Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Sat, 25 Feb 2023 00:23:04 -0500 Subject: [PATCH 1/4] wrapper function to add additoinal request data to error objects. begin working on better silentError handling. --- MVMCoreUI/BaseControllers/ViewController.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index c6c64f3a..02611511 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -133,7 +133,7 @@ import MVMCore } catch let parsingError { // Log all parsing errors and fail load. handleLoggingFor(parsingError: parsingError) - if let errorObject = MVMCoreErrorObject.createErrorObject(for: parsingError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) { + if let errorObject = MVMCoreLoadHandler.sharedGlobal()?.error(for: loadObject, causedBy: parsingError) { errorObject.messageToDisplay = MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess) error.pointee = errorObject } @@ -200,7 +200,8 @@ import MVMCore } guard modulesRequired.count == 0 else { - if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorCritical), messageToLog: modulesRequired.description, code: ErrorCode.requiredModuleNotPresent.rawValue, domain: ErrorDomainNative, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject!)) { + if let loadObject = loadObject, let errorObject = MVMCoreLoadHandler.sharedGlobal()?.error(for: loadObject, withTitle:nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorCritical), code: ErrorCode.requiredModuleNotPresent.rawValue, domain: ErrorDomainNative) { + errorObject.messageToLog = modulesRequired.description error.pointee = errorObject } return false From 6c0f0993a0d75ab4af7482951f46ac4e8814d9a3 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Mon, 6 Mar 2023 15:58:33 -0500 Subject: [PATCH 2/4] Crash fix for missing UserMessage. Suppress alertToShow dialogs when a native error screen is present. Pipe template parsing description messages to error object. Provide a messageToLog for invalid openURL calls. --- .../BaseControllers/ViewController.swift | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 02611511..d9e0065c 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -132,9 +132,9 @@ import MVMCore try parsePageJSON() } catch let parsingError { // Log all parsing errors and fail load. - handleLoggingFor(parsingError: parsingError) if let errorObject = MVMCoreLoadHandler.sharedGlobal()?.error(for: loadObject, causedBy: parsingError) { errorObject.messageToDisplay = MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess) + errorObject.messageToLog = describe(parsingError: parsingError) error.pointee = errorObject } return false @@ -149,37 +149,38 @@ import MVMCore return true } - func handleLoggingFor(parsingError: Error) { + func describe(parsingError: Error) -> String { if let registryError = parsingError as? ModelRegistry.Error { switch (registryError) { case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil: - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })") + return "Error parsing template. Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })" case .decoderErrorObjectNotPresent(let codingKey, codingPath: let codingPath): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })") + return "Error parsing template. Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })" default: - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Registry error: \(registryError)") + return "Error parsing template. Registry error: \((registryError as NSError).localizedFailureReason ?? registryError.localizedDescription)" } } if let decodingError = parsingError as? DecodingError { switch (decodingError) { case .keyNotFound(let codingKey, let context): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })") + return "Error parsing template. Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })" case .valueNotFound(_, let context): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Value not found @ \(context.codingPath.map { return $0.stringValue })") + return "Error parsing template. Value not found @ \(context.codingPath.map { return $0.stringValue })" case .typeMismatch(_, let context): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Type mismatch @ \(context.codingPath.map { return $0.stringValue })") + return "Error parsing template. Type mismatch @ \(context.codingPath.map { return $0.stringValue })" case .dataCorrupted(let context): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Data corrupted @ \(context.codingPath.map { return $0.stringValue })") + return "Error parsing template. Data corrupted @ \(context.codingPath.map { return $0.stringValue })" @unknown default: - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: \(parsingError)") + return "Error parsing template. \((parsingError as NSError).localizedFailureReason ?? parsingError.localizedDescription)" } } + return "Error parsing template. \((parsingError as NSError).localizedFailureReason ?? parsingError.localizedDescription)" } open func parsePageJSON() throws { } From 289a31af241d521b3d1517296fac3b8b23e70686 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Mon, 13 Mar 2023 19:45:58 -0400 Subject: [PATCH 3/4] Prevent double logging and double error popup. --- MVMCoreUI/BaseControllers/ViewController.swift | 3 ++- MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index d9e0065c..339868fe 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -155,7 +155,7 @@ import MVMCore case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil: return "Error parsing template. Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })" - case .decoderErrorObjectNotPresent(let codingKey, codingPath: let codingPath): + case .decoderErrorObjectNotPresent(let codingKey, let codingPath): return "Error parsing template. Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })" default: @@ -475,6 +475,7 @@ import MVMCore open func handleAction(error: Error, model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) { let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType))! + errorObject.silentError = (error as? MVMCoreErrorObject)?.silentError ?? false // Prefer incoming settings, then default to loud. MVMCoreUIActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData) } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift index 24d57f8d..3de8fdde 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift @@ -41,6 +41,7 @@ import SafariServices open override func defaultHandleActionError(_ error: MVMCoreErrorObject, additionalData: [AnyHashable : Any]?) { super.defaultHandleActionError(error, additionalData: additionalData) guard !error.silentError else { return } + error.silentError = true // Silence if this error is triggered again. (Legacy action handler flow.) Task(priority: .userInitiated) { @MainActor in let alertObject = MVMCoreAlertObject.init(popupAlertWithError: error, isGreedy: false)! MVMCoreAlertHandler.shared()?.showAlert(with: alertObject) From 04e85db91e05d67fc9d43c215f25ca0ec06ebe5d Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Wed, 15 Mar 2023 09:04:58 -0400 Subject: [PATCH 4/4] code review --- MVMCoreUI/BaseControllers/ViewController.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 339868fe..18f1e67c 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -165,13 +165,13 @@ import MVMCore if let decodingError = parsingError as? DecodingError { switch (decodingError) { case .keyNotFound(let codingKey, let context): - return "Error parsing template. Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })" + return "Error parsing template. Required key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })" case .valueNotFound(_, let context): return "Error parsing template. Value not found @ \(context.codingPath.map { return $0.stringValue })" case .typeMismatch(_, let context): - return "Error parsing template. Type mismatch @ \(context.codingPath.map { return $0.stringValue })" + return "Error parsing template. Value type mismatch @ \(context.codingPath.map { return $0.stringValue })" case .dataCorrupted(let context): return "Error parsing template. Data corrupted @ \(context.codingPath.map { return $0.stringValue })" @@ -475,7 +475,14 @@ import MVMCore open func handleAction(error: Error, model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) { let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType))! - errorObject.silentError = (error as? MVMCoreErrorObject)?.silentError ?? false // Prefer incoming settings, then default to loud. + + switch (model) { + case let model as ActionOpenPageModel: + errorObject.silentError = model.background ?? false + default: + errorObject.silentError = false + } + MVMCoreUIActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData) }