diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2022-05-19 14:41:11 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2022-05-30 15:00:07 +0200 |
| commit | 3dd480271cbe30d5a4b3586084b1f946cf22080a (patch) | |
| tree | 25e3640c7b1d67311280ab50bad447470d17d47c | |
| parent | 7d3eedafd8821a2a0223f4d35d7020e588cbcfe2 (diff) | |
| download | mullvadvpn-3dd480271cbe30d5a4b3586084b1f946cf22080a.tar.xz mullvadvpn-3dd480271cbe30d5a4b3586084b1f946cf22080a.zip | |
Refactor code to throw errors instead of passing result
| -rw-r--r-- | ios/MullvadVPN/ConsolidatedApplicationLog.swift | 17 | ||||
| -rw-r--r-- | ios/MullvadVPN/Logging/LogRotation.swift | 45 | ||||
| -rw-r--r-- | ios/MullvadVPN/Logging/Logging.swift | 18 | ||||
| -rw-r--r-- | ios/PacketTunnel/Pinger.swift | 22 | ||||
| -rw-r--r-- | ios/PacketTunnel/TunnelMonitor.swift | 27 |
5 files changed, 69 insertions, 60 deletions
diff --git a/ios/MullvadVPN/ConsolidatedApplicationLog.swift b/ios/MullvadVPN/ConsolidatedApplicationLog.swift index e31b6b6371..bd11fac1c9 100644 --- a/ios/MullvadVPN/ConsolidatedApplicationLog.swift +++ b/ios/MullvadVPN/ConsolidatedApplicationLog.swift @@ -15,7 +15,6 @@ private let kRedactedAccountPlaceholder = "[REDACTED ACCOUNT NUMBER]" private let kRedactedContainerPlaceholder = "[REDACTED CONTAINER PATH]" class ConsolidatedApplicationLog: TextOutputStreamable { - typealias Metadata = KeyValuePairs<MetadataKey, String> enum MetadataKey: String { @@ -108,13 +107,13 @@ class ConsolidatedApplicationLog: TextOutputStreamable { let path = fileURL.path let redactedPath = redact(string: path) - switch Self.readFileLossy(path: path, maxBytes: kLogMaxReadBytes) { - case .success(let lossyString): + do { + let lossyString = try Self.readFileLossy(path: path, maxBytes: kLogMaxReadBytes) let redactedString = redact(string: lossyString) - logs.append(LogAttachment(label: redactedPath, content: redactedString)) - case .failure(let error): - addError(message: redactedPath, error: error) + logs.append(LogAttachment(label: redactedPath, content: redactedString)) + } catch { + addError(message: redactedPath, error: AnyChainedError(error)) } } @@ -129,9 +128,9 @@ class ConsolidatedApplicationLog: TextOutputStreamable { ] } - private static func readFileLossy(path: String, maxBytes: UInt64) -> Result<String, Error> { + private static func readFileLossy(path: String, maxBytes: UInt64) throws -> String { guard let fileHandle = FileHandle(forReadingAtPath: path) else { - return .failure(.logFileDoesNotExist(path)) + throw Error.logFileDoesNotExist(path) } let endOfFileOffset = fileHandle.seekToEndOfFile() @@ -149,7 +148,7 @@ class ConsolidatedApplicationLog: TextOutputStreamable { return ch == replacementCharacter }) - return .success(lossyString) + return lossyString } private func redactCustomStrings(string: String) -> String { diff --git a/ios/MullvadVPN/Logging/LogRotation.swift b/ios/MullvadVPN/Logging/LogRotation.swift index 696f7c4a41..16d48b84df 100644 --- a/ios/MullvadVPN/Logging/LogRotation.swift +++ b/ios/MullvadVPN/Logging/LogRotation.swift @@ -24,36 +24,37 @@ enum LogRotation { } } - static func rotateLog(logsDirectory: URL, logFileName: String) -> Result<(), Error> { + static func rotateLog(logsDirectory: URL, logFileName: String) throws { let fileManager = FileManager.default let source = logsDirectory.appendingPathComponent(logFileName) let backup = source.deletingPathExtension().appendingPathExtension("old.log") - return Result { _ = try fileManager.replaceItemAt(backup, withItemAt: source) } - .mapError { (error) -> Error in - // FileManager returns a very obscure error chain so we need to traverse it to find - // the root cause of the error. - var errorCursor: Swift.Error? = error - let cocoaErrorIterator = AnyIterator { () -> CocoaError? in - if let cocoaError = errorCursor as? CocoaError { - errorCursor = cocoaError.underlying - return cocoaError - } else { - errorCursor = nil - return nil - } + do { + _ = try fileManager.replaceItemAt(backup, withItemAt: source) + } catch { + // FileManager returns a very obscure error chain so we need to traverse it to find + // the root cause of the error. + var errorCursor: Swift.Error? = error + let cocoaErrorIterator = AnyIterator { () -> CocoaError? in + if let cocoaError = errorCursor as? CocoaError { + errorCursor = cocoaError.underlying + return cocoaError + } else { + errorCursor = nil + return nil } + } - while let fileError = cocoaErrorIterator.next() { - // .fileNoSuchFile is returned when both backup and source log files do not exist - // .fileReadNoSuchFile is returned when backup exists but source log file does not - if fileError.code == .fileNoSuchFile || fileError.code == .fileReadNoSuchFile, - fileError.url == source { - return .noSourceLogFile - } + while let fileError = cocoaErrorIterator.next() { + // .fileNoSuchFile is returned when both backup and source log files do not exist + // .fileReadNoSuchFile is returned when backup exists but source log file does not + if fileError.code == .fileNoSuchFile || fileError.code == .fileReadNoSuchFile, + fileError.url == source { + throw Error.noSourceLogFile } + } - return .moveSourceLogFile(error) + throw Error.moveSourceLogFile(error) } } } diff --git a/ios/MullvadVPN/Logging/Logging.swift b/ios/MullvadVPN/Logging/Logging.swift index fe5b65b433..55451b677b 100644 --- a/ios/MullvadVPN/Logging/Logging.swift +++ b/ios/MullvadVPN/Logging/Logging.swift @@ -19,7 +19,15 @@ func initLoggingSystem(bundleIdentifier: String, metadata: Logger.Metadata? = ni try? FileManager.default.createDirectory(at: logsDirectoryURL, withIntermediateDirectories: false, attributes: nil) // Rotate log - let logRotationResult = LogRotation.rotateLog(logsDirectory: logsDirectoryURL, logFileName: logFileName) + var logRotationError: Error? + do { + try LogRotation.rotateLog( + logsDirectory: logsDirectoryURL, + logFileName: logFileName + ) + } catch { + logRotationError = error + } // Create an array of log output streams var streams: [TextOutputStream] = [] @@ -52,8 +60,10 @@ func initLoggingSystem(bundleIdentifier: String, metadata: Logger.Metadata? = ni } } - if case .failure(let logRotationError) = logRotationResult { - Logger(label: "LogRotation") - .error(chainedError: logRotationError, message: "Failed to rotate log") + if let logRotationError = logRotationError { + Logger(label: "LogRotation").error( + chainedError: AnyChainedError(logRotationError), + message: "Failed to rotate log" + ) } } diff --git a/ios/PacketTunnel/Pinger.swift b/ios/PacketTunnel/Pinger.swift index fd76fdc5ec..feb0fd678a 100644 --- a/ios/PacketTunnel/Pinger.swift +++ b/ios/PacketTunnel/Pinger.swift @@ -33,14 +33,14 @@ final class Pinger { stop() } - func start(delay: DispatchTimeInterval, repeating repeatInterval: DispatchTimeInterval) -> Result<(), Pinger.Error> { + func start(delay: DispatchTimeInterval, repeating repeatInterval: DispatchTimeInterval) throws { stateLock.lock() defer { stateLock.unlock() } stop() guard let newSocket = CFSocketCreate(kCFAllocatorDefault, AF_INET, SOCK_DGRAM, IPPROTO_ICMP, 0, nil, nil) else { - return .failure(.createSocket) + throw Error.createSocket } let flags = CFSocketGetSocketFlags(newSocket) @@ -48,12 +48,10 @@ final class Pinger { CFSocketSetSocketFlags(newSocket, flags | kCFSocketCloseOnInvalidate) } - if case .failure(let error) = bindSocket(newSocket) { - return .failure(error) - } + try bindSocket(newSocket) guard let runLoop = CFSocketCreateRunLoopSource(kCFAllocatorDefault, newSocket, 0) else { - return .failure(.createRunLoop) + throw Error.createRunLoop } CFRunLoopAddSource(CFRunLoopGetMain(), runLoop, .defaultMode) @@ -68,8 +66,6 @@ final class Pinger { newTimer.schedule(wallDeadline: .now() + delay, repeating: repeatInterval) newTimer.resume() - - return .success(()) } func stop() { @@ -135,15 +131,15 @@ final class Pinger { return nextSequenceNumber } - private func bindSocket(_ socket: CFSocket) -> Result<(), Pinger.Error> { + private func bindSocket(_ socket: CFSocket) throws { guard let interfaceName = interfaceName else { logger.debug("Interface is not specified.") - return .success(()) + return } var index = if_nametoindex(interfaceName) guard index > 0 else { - return .failure(.mapInterfaceNameToIndex(errno)) + throw Error.mapInterfaceNameToIndex(errno) } logger.debug("Bind socket to \"\(interfaceName)\" (index: \(index))...") @@ -159,9 +155,7 @@ final class Pinger { if result == -1 { logger.error("Failed to bind socket to \"\(interfaceName)\" (index: \(index), errno: \(errno)).") - return .failure(.bindSocket(errno)) - } else { - return .success(()) + throw Error.bindSocket(errno) } } diff --git a/ios/PacketTunnel/TunnelMonitor.swift b/ios/PacketTunnel/TunnelMonitor.swift index bec23409f0..b39a26d4d5 100644 --- a/ios/PacketTunnel/TunnelMonitor.swift +++ b/ios/PacketTunnel/TunnelMonitor.swift @@ -125,16 +125,16 @@ final class TunnelMonitor { stopPinging() } - private func startPinging(address: IPv4Address) -> Result<(), Pinger.Error> { + private func startPinging(address: IPv4Address) throws { let newPinger = Pinger(address: address, interfaceName: adapter.interfaceName) - let pingerResult = newPinger.start(delay: TunnelMonitorConfiguration.pingStartDelay, repeating: TunnelMonitorConfiguration.pingInterval) - if case .success = pingerResult { - pinger = newPinger - isPinging = true - } + try newPinger.start( + delay: TunnelMonitorConfiguration.pingStartDelay, + repeating: TunnelMonitorConfiguration.pingInterval + ) - return pingerResult + pinger = newPinger + isPinging = true } private func stopPinging() { @@ -230,8 +230,9 @@ final class TunnelMonitor { case (true, false): logger.debug("Network is reachable. Starting to ping.") - switch startPinging(address: address) { - case .success: + do { + try startPinging(address: address) + // Reset the last recovery attempt date. firstAttemptDate = Date() lastAttemptDate = firstAttemptDate @@ -242,10 +243,14 @@ final class TunnelMonitor { delegateQueue.async { self.delegate?.tunnelMonitor(self, networkReachabilityStatusDidChange: isNetworkReachable) } + } catch { + let error = error as! Pinger.Error - case .failure(let error): if error != lastError { - logger.error(chainedError: AnyChainedError(error), message: "Failed to start pinging.") + logger.error( + chainedError: AnyChainedError(error), + message: "Failed to start pinging." + ) lastError = error } } |
