Better error messages for decoding issues

This commit is contained in:
Stuart Breckenridge 2021-09-21 10:43:12 +08:00
parent c29afd2677
commit 82a62712ce
No known key found for this signature in database
GPG Key ID: 1F11FD62007DC331
6 changed files with 58 additions and 21 deletions

View File

@ -323,7 +323,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
func application(_ sender: NSApplication, openFile filename: String) -> Bool {
guard filename.hasSuffix(ArticleTheme.nnwThemeSuffix) else { return false }
try? importTheme(filename: filename)
importTheme(filename: filename)
return true
}
@ -386,7 +386,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
return
}
DispatchQueue.main.async {
try? self.importTheme(filename: url.path)
self.importTheme(filename: url.path)
}
}
@ -921,11 +921,30 @@ internal extension AppDelegate {
let window = mainWindowController?.window else {
return
}
var informativeText: String = ""
if let decodingError = error as? DecodingError {
switch decodingError {
case .typeMismatch(let type, _):
informativeText = "Type '\(type)' mismatch."
case .valueNotFound(let value, _):
informativeText = "Value '\(value)' not found."
case .keyNotFound(let codingKey, _):
informativeText = "Key '\(codingKey.stringValue)' not found."
case .dataCorrupted( _):
informativeText = error.localizedDescription
default:
informativeText = error.localizedDescription
}
} else {
informativeText = error.localizedDescription
}
DispatchQueue.main.async {
let alert = NSAlert()
alert.alertStyle = .warning
alert.messageText = NSLocalizedString("Theme Error", comment: "Theme download error")
alert.informativeText = NSLocalizedString("This theme cannot be imported due to the following error: \(error.localizedDescription)", comment: "Theme download error information")
alert.informativeText = NSLocalizedString("This theme cannot be imported due to the following error: \(informativeText)", comment: "Theme download error information")
alert.addButton(withTitle: NSLocalizedString("OK", comment: "OK"))
alert.beginSheetModal(for: window)
}

View File

@ -6436,8 +6436,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/marmelroy/Zip.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.0.0;
kind = revision;
revision = 059e7346082d02de16220cd79df7db18ddeba8c3;
};
};
5102AE4324D17E820050839C /* XCRemoteSwiftPackageReference "RSCore" */ = {

View File

@ -123,8 +123,8 @@
"repositoryURL": "https://github.com/marmelroy/Zip.git",
"state": {
"branch": null,
"revision": "bd19d974e8a38cc8d3a88c90c8a107386c3b8ccf",
"version": "2.1.1"
"revision": "059e7346082d02de16220cd79df7db18ddeba8c3",
"version": null
}
}
]

View File

@ -9,13 +9,13 @@
import Foundation
struct ArticleTheme: Equatable {
static let defaultTheme = ArticleTheme()
static let nnwThemeSuffix = ".nnwtheme"
private static let defaultThemeName = NSLocalizedString("Default", comment: "Default")
private static let unknownValue = NSLocalizedString("Unknown", comment: "Unknown Value")
let path: String?
let template: String?
let css: String?
@ -38,26 +38,27 @@ struct ArticleTheme: Equatable {
}
private let info: ArticleThemePlist?
init() {
self.path = nil;
self.info = ArticleThemePlist(name: "Article Theme", themeIdentifier: "com.ranchero.netnewswire.theme.article", creatorHomePage: "https://netnewswire.com/", creatorName: "Ranchero Software", version: 1)
let corePath = Bundle.main.path(forResource: "core", ofType: "css")!
let stylesheetPath = Bundle.main.path(forResource: "stylesheet", ofType: "css")!
css = Self.stringAtPath(corePath)! + "\n" + Self.stringAtPath(stylesheetPath)!
let templatePath = Bundle.main.path(forResource: "template", ofType: "html")!
template = Self.stringAtPath(templatePath)!
}
init(path: String) throws {
self.path = path
let infoPath = (path as NSString).appendingPathComponent("Info.plist")
let data = try Data(contentsOf: URL(fileURLWithPath: infoPath))
self.info = try PropertyListDecoder().decode(ArticleThemePlist.self, from: data)
let corePath = Bundle.main.path(forResource: "core", ofType: "css")!
let stylesheetPath = (path as NSString).appendingPathComponent("stylesheet.css")
if let stylesheetCSS = Self.stringAtPath(stylesheetPath) {
@ -65,7 +66,7 @@ struct ArticleTheme: Equatable {
} else {
self.css = nil
}
let templatePath = (path as NSString).appendingPathComponent("template.html")
self.template = Self.stringAtPath(templatePath)
}
@ -74,22 +75,22 @@ struct ArticleTheme: Equatable {
if !FileManager.default.fileExists(atPath: f) {
return nil
}
if let s = try? NSString(contentsOfFile: f, usedEncoding: nil) as String {
return s
}
return nil
}
static func filenameWithThemeSuffixRemoved(_ filename: String) -> String {
return filename.stripping(suffix: Self.nnwThemeSuffix)
}
static func themeNameForPath(_ f: String) -> String {
let filename = (f as NSString).lastPathComponent
return filenameWithThemeSuffixRemoved(filename)
}
static func pathIsPathForThemeName(_ themeName: String, path: String) -> Bool {
let filename = (path as NSString).lastPathComponent
return filenameWithThemeSuffixRemoved(filename) == themeName

View File

@ -184,7 +184,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
NotificationCenter.default.post(name: .didBeginDownloadingTheme, object: nil)
}
let task = URLSession.shared.downloadTask(with: request) { [weak self] location, response, error in
guard let self = self,
guard
let location = location else { return }
do {

View File

@ -15,6 +15,23 @@ extension UIViewController {
func presentError(_ error: Error, dismiss: (() -> Void)? = nil) {
if let accountError = error as? AccountError, accountError.isCredentialsError {
presentAccountError(accountError, dismiss: dismiss)
} else if let decodingError = error as? DecodingError {
let errorTitle = NSLocalizedString("Error", comment: "Error")
switch decodingError {
case .typeMismatch(let type, _):
let str = "Type '\(type)' mismatch."
presentError(title: errorTitle, message: str, dismiss: dismiss)
case .valueNotFound(let value, _):
let str = "Value '\(value)' not found."
presentError(title: errorTitle, message: str, dismiss: dismiss)
case .keyNotFound(let codingKey, _):
let str = "Key '\(codingKey.stringValue)' not found."
presentError(title: errorTitle, message: str, dismiss: dismiss)
case .dataCorrupted( _):
presentError(title: errorTitle, message: error.localizedDescription, dismiss: dismiss)
default:
presentError(title: errorTitle, message: error.localizedDescription, dismiss: dismiss)
}
} else {
let errorTitle = NSLocalizedString("Error", comment: "Error")
presentError(title: errorTitle, message: error.localizedDescription, dismiss: dismiss)