diff --git a/Shared/WriteFreely_MultiPlatformApp.swift b/Shared/WriteFreely_MultiPlatformApp.swift
index 76ff61b..d17c965 100644
--- a/Shared/WriteFreely_MultiPlatformApp.swift
+++ b/Shared/WriteFreely_MultiPlatformApp.swift
@@ -1,147 +1,148 @@
 import SwiftUI
 
 #if os(macOS)
 import Sparkle
 #endif
 
 @main
 struct CheckForDebugModifier {
     static func main() {
         #if os(macOS)
             if NSEvent.modifierFlags.contains(.shift) {
                 // Clear the launch-to-last-draft values to load a new draft.
                 UserDefaults.shared.setValue(false, forKey: WFDefaults.showAllPostsFlag)
                 UserDefaults.shared.setValue(nil, forKey: WFDefaults.selectedCollectionURL)
                 UserDefaults.shared.setValue(nil, forKey: WFDefaults.lastDraftURL)
             } else {
                 // No-op
             }
         #endif
         WriteFreely_MultiPlatformApp.main()
     }
 }
 
 struct WriteFreely_MultiPlatformApp: App {
     @StateObject private var model = WriteFreelyModel.shared
 
     #if os(macOS)
     @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
     @StateObject var updaterViewModel = MacUpdatesViewModel()
     @State private var selectedTab = 0
     #endif
 
     var body: some Scene {
         WindowGroup {
             ContentView()
                 .onAppear(perform: {
                     if model.editor.showAllPostsFlag {
                         DispatchQueue.main.async {
                             self.model.selectedCollection = nil
                             self.model.showAllPosts = true
                             showLastDraftOrCreateNewLocalPost()
                         }
                     } else {
                         DispatchQueue.main.async {
                             self.model.selectedCollection = model.editor.fetchSelectedCollectionFromAppStorage()
                             self.model.showAllPosts = false
                             showLastDraftOrCreateNewLocalPost()
                         }
                     }
                 })
                 .withErrorHandling()
                 .environmentObject(model)
                 .environment(\.managedObjectContext, LocalStorageManager.standard.container.viewContext)
 //                .preferredColorScheme(preferences.selectedColorScheme)    // See PreferencesModel for info.
         }
         .commands {
             #if os(macOS)
             CommandGroup(after: .appInfo) {
                 CheckForUpdatesView(updaterViewModel: updaterViewModel)
             }
             #endif
             CommandGroup(replacing: .newItem, addition: {
                 Button("New Post") {
                     createNewLocalPost()
                 }
                 .keyboardShortcut("n", modifiers: [.command])
             })
             CommandGroup(after: .newItem) {
                 Button("Refresh Posts") {
                     DispatchQueue.main.async {
                         model.fetchUserCollections()
                         model.fetchUserPosts()
                     }
                 }
                 .disabled(!model.account.isLoggedIn)
                 .keyboardShortcut("r", modifiers: [.command])
             }
             SidebarCommands()
             #if os(macOS)
             PostCommands(model: model)
             #endif
             CommandGroup(after: .help) {
                 Button("Visit Support Forum") {
                     #if os(macOS)
                     NSWorkspace().open(model.helpURL)
                     #else
                     UIApplication.shared.open(model.helpURL)
                     #endif
                 }
             }
             ToolbarCommands()
             TextEditingCommands()
         }
 
         #if os(macOS)
         Settings {
             TabView(selection: $selectedTab) {
                 MacAccountView()
                     .environmentObject(model)
                     .tabItem {
                         Image(systemName: "person.crop.circle")
                         Text("Account")
                     }
                     .tag(0)
                 MacPreferencesView(preferences: model.preferences)
                     .tabItem {
                         Image(systemName: "gear")
                         Text("Preferences")
                     }
                     .tag(1)
                 MacUpdatesView(updaterViewModel: updaterViewModel)
                     .tabItem {
                         Image(systemName: "arrow.down.circle")
                         Text("Updates")
                     }
                     .tag(2)
             }
+            .withErrorHandling()
             .frame(minWidth: 500, maxWidth: 500, minHeight: 200)
             .padding()
 //            .preferredColorScheme(preferences.selectedColorScheme)    // See PreferencesModel for info.
         }
         #endif
     }
 
     private func showLastDraftOrCreateNewLocalPost() {
         if model.editor.lastDraftURL != nil {
             self.model.selectedPost = model.editor.fetchLastDraftFromAppStorage()
         } else {
             createNewLocalPost()
         }
     }
 
     private func createNewLocalPost() {
         withAnimation {
             // Un-set the currently selected post
             self.model.selectedPost = nil
         }
         // Create the new-post managed object
         let managedPost = model.editor.generateNewLocalPost(withFont: model.preferences.font)
         withAnimation {
             // Set it as the selectedPost
             DispatchQueue.main.asyncAfter(deadline: .now()) {
                 self.model.selectedPost = managedPost
             }
         }
     }
 }
diff --git a/macOS/PostEditor/PostEditorView.swift b/macOS/PostEditor/PostEditorView.swift
index 56bedc9..b76e921 100644
--- a/macOS/PostEditor/PostEditorView.swift
+++ b/macOS/PostEditor/PostEditorView.swift
@@ -1,92 +1,103 @@
 import SwiftUI
 
 struct PostEditorView: View {
     @EnvironmentObject var model: WriteFreelyModel
+    @EnvironmentObject var errorHandling: ErrorHandling
 
     @ObservedObject var post: WFAPost
     @State private var isHovering: Bool = false
     @State private var updatingFromServer: Bool = false
 
     var body: some View {
         PostTextEditingView(
             post: post,
             updatingFromServer: $updatingFromServer
         )
         .padding()
         .background(Color(NSColor.controlBackgroundColor))
         .onAppear(perform: {
             if post.status != PostStatus.published.rawValue {
                 DispatchQueue.main.async {
                     self.model.editor.saveLastDraft(post)
                 }
             } else {
                 self.model.editor.clearLastDraft()
             }
         })
         .onChange(of: post.hasNewerRemoteCopy, perform: { _ in
             if !post.hasNewerRemoteCopy {
                 self.updatingFromServer = true
             }
         })
         .onChange(of: post.status, perform: { value in
             if value != PostStatus.published.rawValue {
                 self.model.editor.saveLastDraft(post)
             } else {
                 self.model.editor.clearLastDraft()
             }
             DispatchQueue.main.async {
                 LocalStorageManager.standard.saveContext()
             }
         })
+        .onChange(of: model.hasError) { value in
+            if value {
+                if let error = model.currentError {
+                    self.errorHandling.handle(error: error)
+                } else {
+                    self.errorHandling.handle(error: AppError.genericError())
+                }
+                model.hasError = false
+            }
+        }
         .onDisappear(perform: {
             DispatchQueue.main.async {
                 model.editor.clearLastDraft()
             }
             if post.title.count == 0
                 && post.body.count == 0
                 && post.status == PostStatus.local.rawValue
                 && post.updatedDate == nil
                 && post.postId == nil {
                 DispatchQueue.main.async {
                     model.posts.remove(post)
                 }
             } else if post.status != PostStatus.published.rawValue {
                 DispatchQueue.main.async {
                     LocalStorageManager.standard.saveContext()
                 }
             }
         })
     }
 }
 
 struct PostEditorView_EmptyPostPreviews: PreviewProvider {
     static var previews: some View {
         let context = LocalStorageManager.standard.container.viewContext
         let testPost = WFAPost(context: context)
         testPost.createdDate = Date()
         testPost.appearance = "norm"
 
         let model = WriteFreelyModel()
 
         return PostEditorView(post: testPost)
             .environment(\.managedObjectContext, context)
             .environmentObject(model)
     }
 }
 
 struct PostEditorView_ExistingPostPreviews: PreviewProvider {
     static var previews: some View {
         let context = LocalStorageManager.standard.container.viewContext
         let testPost = WFAPost(context: context)
         testPost.title = "Test Post Title"
         testPost.body = "Here's some cool sample body text."
         testPost.createdDate = Date()
         testPost.appearance = "code"
 
         let model = WriteFreelyModel()
 
         return PostEditorView(post: testPost)
             .environment(\.managedObjectContext, context)
             .environmentObject(model)
     }
 }
diff --git a/macOS/Settings/MacAccountView.swift b/macOS/Settings/MacAccountView.swift
index f0d4c30..9939e99 100644
--- a/macOS/Settings/MacAccountView.swift
+++ b/macOS/Settings/MacAccountView.swift
@@ -1,18 +1,29 @@
 import SwiftUI
 
 struct MacAccountView: View {
     @EnvironmentObject var model: WriteFreelyModel
+    @EnvironmentObject var errorHandling: ErrorHandling
 
     var body: some View {
-            Form {
-                    AccountView()
+        Form {
+            AccountView()
+        }
+        .onChange(of: model.hasError) { value in
+            if value {
+                if let error = model.currentError {
+                    self.errorHandling.handle(error: error)
+                } else {
+                    self.errorHandling.handle(error: AppError.genericError())
+                }
+                model.hasError = false
             }
+        }
     }
 }
 
 struct MacAccountView_Previews: PreviewProvider {
     static var previews: some View {
         MacAccountView()
             .environmentObject(WriteFreelyModel())
     }
 }
diff --git a/macOS/Settings/MacPreferencesView.swift b/macOS/Settings/MacPreferencesView.swift
index 85fa829..feb91e5 100644
--- a/macOS/Settings/MacPreferencesView.swift
+++ b/macOS/Settings/MacPreferencesView.swift
@@ -1,18 +1,31 @@
 import SwiftUI
 
 struct MacPreferencesView: View {
+    @EnvironmentObject var model: WriteFreelyModel
+    @EnvironmentObject var errorHandling: ErrorHandling
+
     @ObservedObject var preferences: PreferencesModel
 
     var body: some View {
         VStack {
             PreferencesView(preferences: preferences)
             Spacer()
         }
+        .onChange(of: model.hasError) { value in
+            if value {
+                if let error = model.currentError {
+                    self.errorHandling.handle(error: error)
+                } else {
+                    self.errorHandling.handle(error: AppError.genericError())
+                }
+                model.hasError = false
+            }
+        }
     }
 }
 
 struct MacPreferencesView_Previews: PreviewProvider {
     static var previews: some View {
         MacPreferencesView(preferences: PreferencesModel())
     }
 }
diff --git a/macOS/Settings/MacUpdatesView.swift b/macOS/Settings/MacUpdatesView.swift
index afb6c48..ba9f6a3 100644
--- a/macOS/Settings/MacUpdatesView.swift
+++ b/macOS/Settings/MacUpdatesView.swift
@@ -1,91 +1,104 @@
 import SwiftUI
 import Sparkle
 
 struct MacUpdatesView: View {
+    @EnvironmentObject var model: WriteFreelyModel
+    @EnvironmentObject var errorHandling: ErrorHandling
+
     @ObservedObject var updaterViewModel: MacUpdatesViewModel
 
     @AppStorage(WFDefaults.automaticallyChecksForUpdates, store: UserDefaults.shared)
     var automaticallyChecksForUpdates: Bool = false
     @AppStorage(WFDefaults.subscribeToBetaUpdates, store: UserDefaults.shared)
     var subscribeToBetaUpdates: Bool = false
 
     @State private var lastUpdateCheck: Date?
 
     private let betaWarningString = """
 To get brand new features before each official release, choose "Test versions." Note that test versions may have bugs \
 that can cause crashes and data loss.
 """
 
     static let lastUpdateFormatter: DateFormatter = {
         let formatter = DateFormatter()
         formatter.dateStyle = .short
         formatter.timeStyle = .short
         formatter.doesRelativeDateFormatting = true
         return formatter
     }()
 
     var body: some View {
         VStack(spacing: 24) {
             Toggle(isOn: $automaticallyChecksForUpdates, label: {
                 Text("Check for updates automatically")
             })
 
             VStack {
                 Button(action: {
                     updaterViewModel.checkForUpdates()
                     // There's a delay between requesting an update, and the timestamp for that update request being
                     // written to user defaults; we therefore delay updating the "Last checked" UI for one second.
                     DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                         lastUpdateCheck = updaterViewModel.getLastUpdateCheckDate()
                     }
                 }, label: {
                     Text("Check For Updates")
                 })
 
                 HStack {
                     Text("Last checked:")
                         .font(.caption)
                     if let lastUpdateCheck = lastUpdateCheck {
                         Text(lastUpdateCheck, formatter: Self.lastUpdateFormatter)
                             .font(.caption)
                     } else {
                         Text("Never")
                             .font(.caption)
                     }
                 }
             }
 
             VStack(spacing: 16) {
                 HStack(alignment: .top) {
                     Text("Download:")
                     Picker(selection: $subscribeToBetaUpdates, label: Text("Download:"), content: {
                         Text("Release versions").tag(false)
                         Text("Test versions").tag(true)
                     })
                     .pickerStyle(RadioGroupPickerStyle())
                     .labelsHidden()
                 }
 
                 Text(betaWarningString)
                     .frame(width: 350)
                     .foregroundColor(.secondary)
             }
         }
         .padding()
         .onAppear {
             lastUpdateCheck = updaterViewModel.getLastUpdateCheckDate()
         }
         .onChange(of: automaticallyChecksForUpdates) { value in
             updaterViewModel.automaticallyCheckForUpdates = value
         }
         .onChange(of: subscribeToBetaUpdates) { _ in
             updaterViewModel.toggleAllowedChannels()
         }
+        .onChange(of: model.hasError) { value in
+            if value {
+                if let error = model.currentError {
+                    self.errorHandling.handle(error: error)
+                } else {
+                    self.errorHandling.handle(error: AppError.genericError())
+                }
+                model.hasError = false
+            }
+        }
     }
 }
 
 struct MacUpdatesView_Previews: PreviewProvider {
     static var previews: some View {
         MacUpdatesView(updaterViewModel: MacUpdatesViewModel())
     }
 }