apple_kit

Apple-native services for Radroots iOS and macOS apps
git clone https://radroots.dev/git/apple_kit.git
Log | Files | Refs | README | LICENSE

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 }