From 95b28a224f70a40303f092de6e644cbcfd560fb9 Mon Sep 17 00:00:00 2001 From: George Barnett Date: Tue, 21 Jan 2025 14:28:05 +0000 Subject: [PATCH 1/2] Allow a Status to be created from an HTTP status code Motivation: gRPC has a well defined mapping of HTTP status codes to gRPC status codes for when a response doesn't explicitly include a gRPC status. Modifications: - Add an init to status to allow for a status to be created from an HTTP status code. Result: Can create a status from an HTTP status code --- Sources/GRPCCore/Status.swift | 29 +++++++++++++++++++++++++++ Tests/GRPCCoreTests/StatusTests.swift | 19 ++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Sources/GRPCCore/Status.swift b/Sources/GRPCCore/Status.swift index 7a78c12e1..e1f3c081a 100644 --- a/Sources/GRPCCore/Status.swift +++ b/Sources/GRPCCore/Status.swift @@ -296,3 +296,32 @@ extension Status.Code { /// operation. public static let unauthenticated = Self(code: .unauthenticated) } + +extension Status { + /// Create a status from an HTTP status code for a response which didn't include a gRPC status. + /// + /// - Parameter httpStatusCode: The HTTP status code to map to a status. + public init(httpStatusCode: Int) { + // https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md + switch httpStatusCode { + case 400: + self = Status(code: .internalError, message: "HTTP 400: Bad Request") + case 401: + self = Status(code: .unauthenticated, message: "HTTP 401: Unauthorized") + case 403: + self = Status(code: .permissionDenied, message: "HTTP 403: Forbidden") + case 404: + self = Status(code: .unimplemented, message: "HTTP 404: Not Found") + case 429: + self = Status(code: .unavailable, message: "HTTP 429: Too Many Requests") + case 502: + self = Status(code: .unavailable, message: "HTTP 502: Bad Gateway") + case 503: + self = Status(code: .unavailable, message: "HTTP 503: Service Unavailable") + case 504: + self = Status(code: .unavailable, message: "HTTP 504: Gateway Timeout") + default: + self = Status(code: .unknown, message: "HTTP \(httpStatusCode)") + } + } +} diff --git a/Tests/GRPCCoreTests/StatusTests.swift b/Tests/GRPCCoreTests/StatusTests.swift index 936ff8e41..fd442586a 100644 --- a/Tests/GRPCCoreTests/StatusTests.swift +++ b/Tests/GRPCCoreTests/StatusTests.swift @@ -69,4 +69,23 @@ struct StatusTests { func fitsInExistentialContainer() { #expect(MemoryLayout.size <= 24) } + + @Test( + "From HTTP status code", + arguments: [ + (400, Status(code: .internalError, message: "HTTP 400: Bad Request")), + (401, Status(code: .unauthenticated, message: "HTTP 401: Unauthorized")), + (403, Status(code: .permissionDenied, message: "HTTP 403: Forbidden")), + (404, Status(code: .unimplemented, message: "HTTP 404: Not Found")), + (429, Status(code: .unavailable, message: "HTTP 429: Too Many Requests")), + (502, Status(code: .unavailable, message: "HTTP 502: Bad Gateway")), + (503, Status(code: .unavailable, message: "HTTP 503: Service Unavailable")), + (504, Status(code: .unavailable, message: "HTTP 504: Gateway Timeout")), + (418, Status(code: .unknown, message: "HTTP 418")), + ] + ) + func convertFromHTTPStatusCode(code: Int, expected: Status) { + let status = Status(httpStatusCode: code) + #expect(status == expected) + } } From 304b5d014d28ded72bf67a3e5bee0f9838c77329 Mon Sep 17 00:00:00 2001 From: George Barnett Date: Wed, 22 Jan 2025 10:39:01 +0000 Subject: [PATCH 2/2] Fix language --- Sources/GRPCCore/Status.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/GRPCCore/Status.swift b/Sources/GRPCCore/Status.swift index e1f3c081a..eba8d54f0 100644 --- a/Sources/GRPCCore/Status.swift +++ b/Sources/GRPCCore/Status.swift @@ -302,7 +302,7 @@ extension Status { /// /// - Parameter httpStatusCode: The HTTP status code to map to a status. public init(httpStatusCode: Int) { - // https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md + // See the "http-grpc-status-mapping.md" doc in grpc/grpc GitHub repo. switch httpStatusCode { case 400: self = Status(code: .internalError, message: "HTTP 400: Bad Request")