// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. // // stringlint:disable import Foundation import SessionUtil public enum LibSessionError: Error, CustomStringConvertible { case unableToCreateConfigObject case nilConfigObject case userDoesNotExist case getOrConstructFailedUnexpectedly case processingLoopLimitReached case invalidCConversion case unableToGeneratePushData case invalidConfigAccess case libSessionError(String) case unknown public init(_ cError: [CChar]) { self = LibSessionError.libSessionError(String(cString: cError)) } public init(_ errorString: String) { switch errorString { default: self = LibSessionError.libSessionError(errorString) } } 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 } public var description: String { switch self { case .unableToCreateConfigObject: return "Unable to create config object (LibSessionError.unableToCreateConfigObject)." case .nilConfigObject: return "Null config object (LibSessionError.nilConfigObject)." 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 .invalidCConversion: return "Invalid conversation to C type (LibSessionError.invalidCConversion)." case .unableToGeneratePushData: return "Unable to generate push data (LibSessionError.unableToGeneratePushData)." case .invalidConfigAccess: return "Invalid config access (LibSessionError.invalidConfigAccess)." case .libSessionError(let error): return "\(error)\(error.hasSuffix(".") ? "" : ".")" case .unknown: return "An unknown error occurred (LibSessionError.unknown)." } } }