RadrootsAppleFileError.swift (2041B)
1 import Darwin 2 import Foundation 3 4 public enum RadrootsAppleFileError: Error, Equatable, Sendable { 5 case invalidRequest 6 case notFound 7 case permissionDenied 8 case transientFailure 9 case permanentFailure 10 /// Capacity is exhausted. Earlier installation may still require reconciliation. 11 case spaceInsufficient 12 } 13 14 extension RadrootsAppleFileError: LocalizedError { 15 public var errorDescription: String? { 16 switch self { 17 case .invalidRequest: "The file request is invalid." 18 case .notFound: "The file was not found." 19 case .permissionDenied: "File access was denied." 20 case .transientFailure: "The file operation could not be completed temporarily." 21 case .permanentFailure: "The file operation could not be completed." 22 case .spaceInsufficient: "There is not enough storage space to complete the file operation." 23 } 24 } 25 } 26 27 extension RadrootsAppleFileError { 28 /// Call only with errno captured from an actually failed system call. 29 static func posix(_ code: Int32) -> Self { 30 code == ENOSPC || code == EDQUOT ? .spaceInsufficient : .permanentFailure 31 } 32 33 static func classified(_ error: any Error) -> Self { 34 if let typed = error as? Self { return typed } 35 var current = error as NSError 36 // Foundation may wrap a POSIX failure. Bound traversal even for a 37 // malformed/cyclic error chain; never retain paths or diagnostic text. 38 for _ in 0 ..< 8 { 39 if current.domain == NSPOSIXErrorDomain, 40 current.code == Int(ENOSPC) || current.code == Int(EDQUOT) { 41 return .spaceInsufficient 42 } 43 if current.domain == NSCocoaErrorDomain, 44 current.code == CocoaError.Code.fileWriteOutOfSpace.rawValue { 45 return .spaceInsufficient 46 } 47 guard let underlying = current.userInfo[NSUnderlyingErrorKey] as? NSError else { break } 48 current = underlying 49 } 50 return .permanentFailure 51 } 52 }