summaryrefslogtreecommitdiff
path: root/Hutch/Networking/SRHTError.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-03-17 23:19:43 -0500
committerChristian Cleberg <[email protected]>2026-03-17 23:19:43 -0500
commit32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5 (patch)
treeee36d421d704e508d5617d803b4c8cbdb4804fe1 /Hutch/Networking/SRHTError.swift
parent8f2057c53e9009c2529c9c4849c914666c0e4b40 (diff)
downloadhutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.tar.gz
hutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.tar.bz2
hutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.zip
v1.0
Diffstat (limited to 'Hutch/Networking/SRHTError.swift')
-rw-r--r--Hutch/Networking/SRHTError.swift63
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
+}