Error handling: Use WireGuardAppError and WireGuardResult throughout the app

This commit is contained in:
Roopesh Chander 2018-12-06 19:05:46 +05:30
parent 8d58a79272
commit cc39342e6e
5 changed files with 45 additions and 41 deletions

View File

@ -5,37 +5,10 @@ import UIKit
import os.log
class ErrorPresenter {
static func errorMessage(for error: Error) -> (String, String) {
if let error = error as? WireGuardAppError {
return error.alertText()
}
switch (error) {
// Importing a zip file
case ZipArchiveError.cantOpenInputZipFile:
return ("Unable to read zip archive", "The zip archive could not be read.")
case ZipArchiveError.badArchive:
return ("Unable to read zip archive", "Bad or corrupt zip archive.")
case ZipImporterError.noTunnelsInZipArchive:
return ("No tunnels in zip archive", "No .conf tunnel files were found inside the zip archive.")
// Exporting a zip file
case ZipArchiveError.cantOpenOutputZipFileForWriting:
return ("Unable to create zip archive", "Could not create a zip file in the app's document directory.")
case ZipExporterError.noTunnelsToExport:
return ("Nothing to export", "There are no tunnels to export")
default:
return ("Error", error.localizedDescription)
}
}
static func showErrorAlert(error: Error, from sourceVC: UIViewController?,
static func showErrorAlert(error: WireGuardAppError, from sourceVC: UIViewController?,
onDismissal: (() -> Void)? = nil, onPresented: (() -> Void)? = nil) {
guard let sourceVC = sourceVC else { return }
let (title, message) = ErrorPresenter.errorMessage(for: error)
let (title, message) = error.alertText()
let okAction = UIAlertAction(title: "OK", style: .default) { (_) in
onDismissal?()
}

View File

@ -165,11 +165,12 @@ class TunnelsListTableViewController: UIViewController {
func importFromFile(url: URL) {
guard let tunnelsManager = tunnelsManager else { return }
if (url.pathExtension == "zip") {
ZipImporter.importConfigFiles(from: url) { (configs, error) in
if let error = error {
ZipImporter.importConfigFiles(from: url) { [weak self] result in
if let error = result.error {
ErrorPresenter.showErrorAlert(error: error, from: self)
return
}
let configs: [TunnelConfiguration?] = result.value!
tunnelsManager.addMultiple(tunnelConfigurations: configs.compactMap { $0 }) { [weak self] (numberSuccessful) in
if numberSuccessful == configs.count {
return

View File

@ -3,10 +3,21 @@
import Foundation
enum ZipArchiveError: Error {
enum ZipArchiveError: WireGuardAppError {
case cantOpenInputZipFile
case cantOpenOutputZipFileForWriting
case badArchive
func alertText() -> (String, String) {
switch (self) {
case .cantOpenInputZipFile:
return ("Unable to read zip archive", "The zip archive could not be read.")
case .cantOpenOutputZipFileForWriting:
return ("Unable to create zip archive", "Could not open zip file for writing.")
case .badArchive:
return ("Unable to read zip archive", "Bad or corrupt zip archive.")
}
}
}
class ZipArchive {

View File

@ -3,12 +3,20 @@
import UIKit
enum ZipExporterError: Error {
enum ZipExporterError: WireGuardAppError {
case noTunnelsToExport
func alertText() -> (String, String) {
switch (self) {
case .noTunnelsToExport:
return ("Nothing to export", "There are no tunnels to export")
}
}
}
class ZipExporter {
static func exportConfigFiles(tunnelConfigurations: [TunnelConfiguration], to url: URL, completion: @escaping (Error?) -> Void) {
static func exportConfigFiles(tunnelConfigurations: [TunnelConfiguration], to url: URL,
completion: @escaping (WireGuardAppError?) -> Void) {
guard (!tunnelConfigurations.isEmpty) else {
completion(ZipExporterError.noTunnelsToExport)
@ -27,9 +35,11 @@ class ZipExporter {
}
do {
try ZipArchive.archive(inputs: inputsToArchiver, to: url)
} catch (let e) {
DispatchQueue.main.async { completion(e) }
} catch (let error as WireGuardAppError) {
DispatchQueue.main.async { completion(error) }
return
} catch {
fatalError()
}
DispatchQueue.main.async { completion(nil) }
}

View File

@ -3,12 +3,19 @@
import UIKit
enum ZipImporterError: Error {
enum ZipImporterError: WireGuardAppError {
case noTunnelsInZipArchive
func alertText() -> (String, String) {
switch (self) {
case .noTunnelsInZipArchive:
return ("No tunnels in zip archive", "No .conf tunnel files were found inside the zip archive.")
}
}
}
class ZipImporter {
static func importConfigFiles(from url: URL, completion: @escaping ([TunnelConfiguration?], Error?) -> Void) {
static func importConfigFiles(from url: URL, completion: @escaping (WireGuardResult<[TunnelConfiguration?]>) -> Void) {
DispatchQueue.global(qos: .userInitiated).async {
var unarchivedFiles: [(fileName: String, contents: Data)]
do {
@ -26,9 +33,11 @@ class ZipImporter {
if (unarchivedFiles.isEmpty) {
throw ZipImporterError.noTunnelsInZipArchive
}
} catch (let error) {
DispatchQueue.main.async { completion([], error) }
} catch (let error as WireGuardAppError) {
DispatchQueue.main.async { completion(.failure(error)) }
return
} catch {
fatalError()
}
unarchivedFiles.sort { $0.fileName < $1.fileName }
@ -45,7 +54,7 @@ class ZipImporter {
}
configs[i] = tunnelConfig
}
DispatchQueue.main.async { completion(configs, nil) }
DispatchQueue.main.async { completion(.success(configs)) }
}
}
}