// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. // // stringlint:disable import Foundation import SessionUtil public enum LibSessionError: Error, CustomStringConvertible { case unableToCreateConfigObject case invalidConfigObject case invalidDataProvided case invalidConfigAccess case userDoesNotExist case getOrConstructFailedUnexpectedly case processingLoopLimitReached case failedToRetrieveConfigData case failedToRekeyGroup case failedToKeySupplementGroup case failedToMakeSubAccountInGroup case invalidCConversion case unableToGeneratePushData case attemptedToModifyGroupWithoutAdminKey case libSessionError(String) public init(_ cError: [CChar]) { self = LibSessionError.libSessionError(String(cString: cError)) } public init(_ errorString: String) { switch errorString { default: self = LibSessionError.libSessionError(errorString) } } // MARK: - Config public init?(_ conf: UnsafeMutablePointer?) { guard let lastErrorPtr: UnsafePointer = conf?.pointee.last_error else { return nil } let errorString = String(cString: lastErrorPtr) conf?.pointee.last_error = nil // Clear the last error so subsequent calls don't get confused self = LibSessionError.libSessionError(errorString) } public init( _ conf: UnsafeMutablePointer?, fallbackError: LibSessionError, logMessage: String? = nil ) { self = (LibSessionError(conf) ?? fallbackError) if let logMessage: String = logMessage { Log.error("\(logMessage): \(self)") } } public static func throwIfNeeded( _ conf: UnsafeMutablePointer?, beforeThrow: (() -> ())? = nil ) throws { guard let error: LibSessionError = LibSessionError(conf) else { return } beforeThrow?() throw error } public static func clear(_ conf: UnsafeMutablePointer?) { conf?.pointee.last_error = nil } // MARK: - GroupKeys public init?(_ conf: UnsafeMutablePointer?) { guard let lastErrorPtr: UnsafePointer = conf?.pointee.last_error else { return nil } let errorString = String(cString: lastErrorPtr) conf?.pointee.last_error = nil // Clear the last error so subsequent calls don't get confused self = LibSessionError.libSessionError(errorString) } public init( _ conf: UnsafeMutablePointer?, fallbackError: LibSessionError, logMessage: String? = nil ) { self = (LibSessionError(conf) ?? fallbackError) if let logMessage: String = logMessage { Log.error(.libSession, "\(logMessage): \(self)") } } public static func throwIfNeeded( _ conf: UnsafeMutablePointer?, beforeThrow: (() -> ())? = nil ) throws { guard let error: LibSessionError = LibSessionError(conf) else { return } beforeThrow?() throw error } public static func clear(_ conf: UnsafeMutablePointer?) { conf?.pointee.last_error = nil } public func logging(_ logMessage: String? = nil, as level: Log.Level = .error) -> LibSessionError { switch logMessage { case .some(let msg): Log.custom(level, [.libSession], "\(msg): \(self)") case .none: Log.custom(level, [.libSession], "\(self)") } return self } // MARK: - CustomStringConvertible public var description: String { switch self { case .unableToCreateConfigObject: return "Unable to create config object (LibSessionError.unableToCreateConfigObject)." case .invalidConfigObject: return "Invalid config object (LibSessionError.invalidConfigObject)." case .invalidDataProvided: return "Invalid data provided (LibSessionError.invalidDataProvided)." case .invalidConfigAccess: return "Invalid config access (LibSessionError.invalidConfigAccess)." case .userDoesNotExist: return "User does not exist (LibSessionError.userDoesNotExist)." case .getOrConstructFailedUnexpectedly: return "'getOrConstruct' failed unexpectedly (LibSessionError.getOrConstructFailedUnexpectedly)." case .processingLoopLimitReached: return "Processing loop limit reached (LibSessionError.processingLoopLimitReached)." case .failedToRetrieveConfigData: return "Failed to retrieve config data (LibSessionError.failedToRetrieveConfigData)." case .failedToRekeyGroup: return "Failed to rekey group (LibSessionError.failedToRekeyGroup)." case .failedToKeySupplementGroup: return "Failed to key supplement group (LibSessionError.failedToKeySupplementGroup)." case .failedToMakeSubAccountInGroup: return "Failed to make subaccount in group (LibSessionError.failedToMakeSubAccountInGroup)." case .invalidCConversion: return "Invalid conversation to C type (LibSessionError.invalidCConversion)." case .unableToGeneratePushData: return "Unable to generate push data (LibSessionError.unableToGeneratePushData)." case .attemptedToModifyGroupWithoutAdminKey: return "Attempted to modify group without admin key (LibSessionError.attemptedToModifyGroupWithoutAdminKey)." case .libSessionError(let error): return "\(error)" } } }