Error handling: Use WireGuardAppError and WireGuardResult throughout the app
This commit is contained in:
parent
8d58a79272
commit
cc39342e6e
|
@ -5,37 +5,10 @@ import UIKit
|
||||||
import os.log
|
import os.log
|
||||||
|
|
||||||
class ErrorPresenter {
|
class ErrorPresenter {
|
||||||
static func errorMessage(for error: Error) -> (String, String) {
|
static func showErrorAlert(error: WireGuardAppError, from sourceVC: UIViewController?,
|
||||||
|
|
||||||
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?,
|
|
||||||
onDismissal: (() -> Void)? = nil, onPresented: (() -> Void)? = nil) {
|
onDismissal: (() -> Void)? = nil, onPresented: (() -> Void)? = nil) {
|
||||||
guard let sourceVC = sourceVC else { return }
|
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
|
let okAction = UIAlertAction(title: "OK", style: .default) { (_) in
|
||||||
onDismissal?()
|
onDismissal?()
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,11 +165,12 @@ class TunnelsListTableViewController: UIViewController {
|
||||||
func importFromFile(url: URL) {
|
func importFromFile(url: URL) {
|
||||||
guard let tunnelsManager = tunnelsManager else { return }
|
guard let tunnelsManager = tunnelsManager else { return }
|
||||||
if (url.pathExtension == "zip") {
|
if (url.pathExtension == "zip") {
|
||||||
ZipImporter.importConfigFiles(from: url) { (configs, error) in
|
ZipImporter.importConfigFiles(from: url) { [weak self] result in
|
||||||
if let error = error {
|
if let error = result.error {
|
||||||
ErrorPresenter.showErrorAlert(error: error, from: self)
|
ErrorPresenter.showErrorAlert(error: error, from: self)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let configs: [TunnelConfiguration?] = result.value!
|
||||||
tunnelsManager.addMultiple(tunnelConfigurations: configs.compactMap { $0 }) { [weak self] (numberSuccessful) in
|
tunnelsManager.addMultiple(tunnelConfigurations: configs.compactMap { $0 }) { [weak self] (numberSuccessful) in
|
||||||
if numberSuccessful == configs.count {
|
if numberSuccessful == configs.count {
|
||||||
return
|
return
|
||||||
|
|
|
@ -3,10 +3,21 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum ZipArchiveError: Error {
|
enum ZipArchiveError: WireGuardAppError {
|
||||||
case cantOpenInputZipFile
|
case cantOpenInputZipFile
|
||||||
case cantOpenOutputZipFileForWriting
|
case cantOpenOutputZipFileForWriting
|
||||||
case badArchive
|
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 {
|
class ZipArchive {
|
||||||
|
|
|
@ -3,12 +3,20 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
enum ZipExporterError: Error {
|
enum ZipExporterError: WireGuardAppError {
|
||||||
case noTunnelsToExport
|
case noTunnelsToExport
|
||||||
|
|
||||||
|
func alertText() -> (String, String) {
|
||||||
|
switch (self) {
|
||||||
|
case .noTunnelsToExport:
|
||||||
|
return ("Nothing to export", "There are no tunnels to export")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ZipExporter {
|
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 {
|
guard (!tunnelConfigurations.isEmpty) else {
|
||||||
completion(ZipExporterError.noTunnelsToExport)
|
completion(ZipExporterError.noTunnelsToExport)
|
||||||
|
@ -27,9 +35,11 @@ class ZipExporter {
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
try ZipArchive.archive(inputs: inputsToArchiver, to: url)
|
try ZipArchive.archive(inputs: inputsToArchiver, to: url)
|
||||||
} catch (let e) {
|
} catch (let error as WireGuardAppError) {
|
||||||
DispatchQueue.main.async { completion(e) }
|
DispatchQueue.main.async { completion(error) }
|
||||||
return
|
return
|
||||||
|
} catch {
|
||||||
|
fatalError()
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async { completion(nil) }
|
DispatchQueue.main.async { completion(nil) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,19 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
enum ZipImporterError: Error {
|
enum ZipImporterError: WireGuardAppError {
|
||||||
case noTunnelsInZipArchive
|
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 {
|
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 {
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
var unarchivedFiles: [(fileName: String, contents: Data)]
|
var unarchivedFiles: [(fileName: String, contents: Data)]
|
||||||
do {
|
do {
|
||||||
|
@ -26,9 +33,11 @@ class ZipImporter {
|
||||||
if (unarchivedFiles.isEmpty) {
|
if (unarchivedFiles.isEmpty) {
|
||||||
throw ZipImporterError.noTunnelsInZipArchive
|
throw ZipImporterError.noTunnelsInZipArchive
|
||||||
}
|
}
|
||||||
} catch (let error) {
|
} catch (let error as WireGuardAppError) {
|
||||||
DispatchQueue.main.async { completion([], error) }
|
DispatchQueue.main.async { completion(.failure(error)) }
|
||||||
return
|
return
|
||||||
|
} catch {
|
||||||
|
fatalError()
|
||||||
}
|
}
|
||||||
|
|
||||||
unarchivedFiles.sort { $0.fileName < $1.fileName }
|
unarchivedFiles.sort { $0.fileName < $1.fileName }
|
||||||
|
@ -45,7 +54,7 @@ class ZipImporter {
|
||||||
}
|
}
|
||||||
configs[i] = tunnelConfig
|
configs[i] = tunnelConfig
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async { completion(configs, nil) }
|
DispatchQueue.main.async { completion(.success(configs)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue