Error handling: Use WireGuardAppError and WireGuardResult throughout the app
Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
parent
782dd2ea4e
commit
dcfa9473e9
|
@ -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?()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
|
|
@ -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)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue