diff options
Diffstat (limited to 'Hutch/Networking/SRHTError.swift')
| -rw-r--r-- | Hutch/Networking/SRHTError.swift | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/Hutch/Networking/SRHTError.swift b/Hutch/Networking/SRHTError.swift new file mode 100644 index 0000000..f148c00 --- /dev/null +++ b/Hutch/Networking/SRHTError.swift @@ -0,0 +1,63 @@ +import Foundation + +/// Errors produced by the Sourcehut GraphQL client. +enum SRHTError: LocalizedError, Sendable { + /// The server returned one or more GraphQL-level errors. + case graphQLErrors([GraphQLError]) + /// The HTTP response had a non-2xx status code. + case httpError(Int) + /// The response data could not be decoded. + case decodingError(any Error) + /// A networking error from URLSession (timeout, DNS, connectivity, etc.). + case networkError(any Error) + /// 401 or no authentication token configured. + case unauthorized + + var errorDescription: String? { + switch self { + case .graphQLErrors(let errors): + let messages = errors.map(\.message).joined(separator: "\n") + return "GraphQL error: \(messages)" + case .httpError(let code): + return "Server returned HTTP \(code)." + case .decodingError(let error): + return "Failed to decode response: \(error.localizedDescription)" + case .networkError(let error): + return "Network error: \(error.localizedDescription)" + case .unauthorized: + return "Authentication required. Please sign in again." + } + } + + /// Whether this error represents a connectivity issue (no internet, timeout, DNS). + var isConnectivityError: Bool { + switch self { + case .networkError(let error): + let nsError = error as NSError + let connectivityCodes: Set<Int> = [ + NSURLErrorNotConnectedToInternet, + NSURLErrorNetworkConnectionLost, + NSURLErrorTimedOut, + NSURLErrorCannotFindHost, + NSURLErrorCannotConnectToHost, + NSURLErrorDNSLookupFailed, + NSURLErrorInternationalRoamingOff, + NSURLErrorDataNotAllowed + ] + return connectivityCodes.contains(nsError.code) + default: + return false + } + } +} + +/// A single error entry from the GraphQL `errors` array. +struct GraphQLError: Decodable, Sendable { + let message: String + let locations: [GraphQLErrorLocation]? +} + +struct GraphQLErrorLocation: Decodable, Sendable { + let line: Int + let column: Int +} |
