Преглед изворни кода

Add error handling and UI alerting for NS profile import

Deniz Cengiz пре 1 година
родитељ
комит
7d1b37a6de

+ 20 - 15
FreeAPS/Sources/Modules/NightscoutConfig/NightscoutConfigStateModel.swift

@@ -140,7 +140,7 @@ extension NightscoutConfig {
                     throw NSError(
                         domain: "ImportError",
                         code: 1,
-                        userInfo: [NSLocalizedDescriptionKey: "Can't find the default Nightscout Profile."]
+                        userInfo: [NSLocalizedDescriptionKey: "Cannot find the default Nightscout Profile."]
                     )
                 }
 
@@ -159,7 +159,6 @@ extension NightscoutConfig {
 
                 if carbratios.contains(where: { $0.ratio <= 0 }) {
                     importStatus = .failed
-
                     throw NSError(
                         domain: "ImportError",
                         code: 2,
@@ -181,22 +180,20 @@ extension NightscoutConfig {
 
                 if pumpName != "Omnipod DASH", basals.contains(where: { $0.rate <= 0 }) {
                     importStatus = .failed
-
                     throw NSError(
                         domain: "ImportError",
                         code: 3,
-                        userInfo: [NSLocalizedDescriptionKey: "Invalid Nightscout Basal Settings. Import aborted."]
+                        userInfo: [NSLocalizedDescriptionKey: "Invalid Nightscout basal rates found. Import aborted."]
                     )
                 }
 
                 if pumpName == "Omnipod DASH", basals.reduce(0, { $0 + $1.rate }) <= 0 {
                     importStatus = .failed
-
                     throw NSError(
                         domain: "ImportError",
                         code: 4,
                         userInfo: [
-                            NSLocalizedDescriptionKey: "Total Basal insulin amount is 0 or lower in Nightscout Profile settings. Import aborted."
+                            NSLocalizedDescriptionKey: "Invalid Nightscout basal rates found. Basal rate total cannot be 0 U/hr. Import aborted."
                         ]
                     )
                 }
@@ -213,11 +210,10 @@ extension NightscoutConfig {
 
                 if sensitivities.contains(where: { $0.sensitivity <= 0 }) {
                     importStatus = .failed
-
                     throw NSError(
                         domain: "ImportError",
                         code: 5,
-                        userInfo: [NSLocalizedDescriptionKey: "Invalid Nightscout Sensitivities Settings. Import aborted."]
+                        userInfo: [NSLocalizedDescriptionKey: "Invalid Nightscout insulin sensitivity profile. Import aborted."]
                     )
                 }
 
@@ -227,8 +223,6 @@ extension NightscoutConfig {
                     sensitivities: sensitivities
                 )
 
-                debug(.nightscout, "FETCHED SENSITIVITIES: \(sensitivitiesProfile)")
-
                 // Targets
                 let targets = fetchedProfile.target_low.map { target in
                     BGTargetEntry(
@@ -241,8 +235,6 @@ extension NightscoutConfig {
 
                 let targetsProfile = BGTargets(units: .mgdL, userPreferredUnits: .mgdL, targets: targets)
 
-                debug(.nightscout, "FETCHED TARGETS: \(targetsProfile)")
-
                 // Save to storage and pump
                 if let pump = apsManager.pumpManager {
                     let syncValues = basals.map {
@@ -261,11 +253,21 @@ extension NightscoutConfig {
                             )
                         case .failure:
                             self.importErrors.append(
-                                "Settings were imported but the Basals couldn't be saved to pump (communication error)."
+                                "Settings were imported but the basal rates could not be saved to pump (communication error)."
                             )
                             self.importStatus = .failed
                         }
                     }
+
+                    if importErrors.isNotEmpty, importStatus == .failed {
+                        throw NSError(
+                            domain: "ImportError",
+                            code: 6,
+                            userInfo: [
+                                NSLocalizedDescriptionKey: "Settings were imported but the basal rates could not be saved to pump (communication error)."
+                            ]
+                        )
+                    }
                 } else {
                     storage.save(basals, as: OpenAPS.Settings.basalProfile)
                     finalizeImport(
@@ -276,8 +278,10 @@ extension NightscoutConfig {
                     )
                 }
             } catch {
-                importErrors.append(error.localizedDescription)
-                debug(.service, "Settings import failed with error: \(error.localizedDescription)")
+                DispatchQueue.main.async {
+                    self.importErrors.append(error.localizedDescription)
+                    debug(.service, "Settings import failed with error: \(error.localizedDescription)")
+                }
             }
         }
 
@@ -375,5 +379,6 @@ extension NightscoutConfig.StateModel {
         case running
         case finished
         case failed
+        case noPumpConnected
     }
 }

+ 16 - 20
FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift

@@ -35,20 +35,6 @@ extension NightscoutConfig {
                 )
         }
 
-        @FetchRequest(
-            entity: ImportError.entity(),
-            sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)], predicate: NSPredicate(
-                format: "date > %@", Date().addingTimeInterval(-1.minutes.timeInterval) as NSDate
-            )
-        ) var fetchedErrors: FetchedResults<ImportError>
-
-        private var portFormater: NumberFormatter {
-            let formatter = NumberFormatter()
-            formatter.allowsFloats = false
-            formatter.usesGroupingSeparator = false
-            return formatter
-        }
-
         var body: some View {
             ZStack {
                 Form {
@@ -67,16 +53,26 @@ extension NightscoutConfig {
                                 importAlert = Alert(
                                     title: Text("Import Therapy Settings?"),
                                     message: Text(
-                                        NSLocalizedString(
-                                            "This will replace some or all of your current therapy settings. Are you sure you want to import profile settings from Nightscout?",
-                                            comment: "Nightscout Settings Import Alert"
-                                        )
+                                        "Are you sure you want to import profile settings from Nightscout?\n\nThis will overwrite the following Trio therapy settings: Basal Rates, Insulin Sensitivities, Carb Ratios, Target Glucose, and Duration of Insulin Action."
                                     ),
                                     primaryButton: .default(
                                         Text("Yes, Import!"),
                                         action: {
                                             Task {
                                                 await state.importSettings()
+                                                // Check the import status and errors after the import process finishes
+                                                if state.importStatus == .failed, state.importErrors.isNotEmpty,
+                                                   let errorMessage = state.importErrors.first
+                                                {
+                                                    DispatchQueue.main.async {
+                                                        importAlert = Alert(
+                                                            title: Text("Import Failed"),
+                                                            message: Text(errorMessage.description),
+                                                            dismissButton: .default(Text("OK"))
+                                                        )
+                                                        isImportAlertPresented = true
+                                                    }
+                                                }
                                             }
                                         }
                                     ),
@@ -102,7 +98,7 @@ extension NightscoutConfig {
                                     action: {
                                         hintLabel = "Import Settings from Nightscout"
                                         selectedVerboseHint =
-                                            "Importing settings from Nightscout will overwrite the following Trio therapy settings: \n • DIA (Pump settings) \n • Basal Profile \n • Insulin Sensitivities \n • Carb Ratios \n • Target Glucose"
+                                            "This will overwrite the following Trio therapy settings: \n • Basal Rates \n • Insulin Sensitivities \n • Carb Ratios \n • Target Glucose \n • Duration of Insulin Action"
                                         shouldDisplayHint.toggle()
                                     },
                                     label: {
@@ -176,7 +172,7 @@ extension NightscoutConfig {
             .navigationBarTitle("Nightscout")
             .navigationBarTitleDisplayMode(.automatic)
             .alert(isPresented: $isImportAlertPresented) {
-                importAlert!
+                importAlert ?? Alert(title: Text("Unknown Error"))
             }
             .scrollContentBackground(.hidden).background(color)
             .onAppear(perform: configureView)

+ 3 - 9
FreeAPS/Sources/Modules/NightscoutConfig/View/ProfileImport/NightscoutImportResultView.swift

@@ -50,8 +50,9 @@ struct NightscoutImportResultView: BaseView {
                     header: Text("Imported Nightscout Data"),
                     content: {
                         Text(
-                            "Trio has successfully imported your default Nightscout profile and applied it as therapy settings. This has replaced your previous therapy settings."
-                        )
+                            "Trio has successfully imported your default Nightscout profile and stored it as therapy settings. "
+                        ) +
+                            Text("This has replaced your previous therapy settings.").bold().foregroundColor(.accentColor)
                         Text("Please review the following settings:").bold()
                     }
                 ).listRowBackground(Color.chart)
@@ -131,13 +132,6 @@ struct NightscoutImportResultView: BaseView {
                     }
                 }.listRowBackground(allViewsVisited ? Color(.systemBlue) : Color(.systemGray4))
             }
-//            .toolbar(content: {
-//                ToolbarItem(placement: .topBarLeading) {
-//                    Button(action: { state.isImportResultReviewPresented = false }, label: {
-//                        Text("Cancel")
-//                    })
-//                }
-//            })
             .navigationTitle("Review Import")
             .navigationBarTitleDisplayMode(.large)
             .scrollContentBackground(.hidden).background(color)

+ 1 - 1
FreeAPS/Sources/Modules/NightscoutConfig/View/ProfileImport/ReviewInsulinActionView.swift

@@ -65,7 +65,7 @@ struct ReviewInsulinActionView: BaseView {
         }
         .scrollContentBackground(.hidden).background(color)
         .onAppear(perform: configureView)
-        .navigationTitle("DIA")
+        .navigationTitle("Duration of Insulin Action")
         .navigationBarTitleDisplayMode(.automatic)
         .onDisappear {
             state.saveReviewedInsulinAction()