GRPCStatus.swift 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import Foundation
  2. import NIO
  3. import NIOHTTP1
  4. import NIOHTTP2
  5. /// Encapsulates the result of a gRPC call.
  6. public struct GRPCStatus: Error, Equatable {
  7. /// The code to return in the `grpc-status` header.
  8. public let code: StatusCode
  9. /// The message to return in the `grpc-message` header.
  10. public let message: String?
  11. /// Additional HTTP headers to return in the trailers.
  12. public let trailingMetadata: HTTPHeaders
  13. public init(code: StatusCode, message: String?, trailingMetadata: HTTPHeaders = HTTPHeaders()) {
  14. self.code = code
  15. self.message = message
  16. self.trailingMetadata = trailingMetadata
  17. }
  18. // Frequently used "default" statuses.
  19. /// The default status to return for succeeded calls.
  20. public static let ok = GRPCStatus(code: .ok, message: "OK")
  21. /// "Internal server error" status.
  22. public static let processingError = GRPCStatus(code: .internalError, message: "unknown error processing request")
  23. }
  24. public protocol GRPCStatusTransformable: Error {
  25. func asGRPCStatus() -> GRPCStatus
  26. }
  27. extension GRPCStatus: GRPCStatusTransformable {
  28. public func asGRPCStatus() -> GRPCStatus {
  29. return self
  30. }
  31. }
  32. extension NIOHTTP2Errors.StreamClosed: GRPCStatusTransformable {
  33. public func asGRPCStatus() -> GRPCStatus {
  34. return .init(code: .unavailable, message: self.localizedDescription)
  35. }
  36. }
  37. extension NIOHTTP2Errors.IOOnClosedConnection: GRPCStatusTransformable {
  38. public func asGRPCStatus() -> GRPCStatus {
  39. return .init(code: .unavailable, message: "The connection is closed")
  40. }
  41. }
  42. extension ChannelError: GRPCStatusTransformable {
  43. public func asGRPCStatus() -> GRPCStatus {
  44. switch self {
  45. case .inputClosed, .outputClosed, .ioOnClosedChannel:
  46. return .init(code: .unavailable, message: "The connection is closed")
  47. default:
  48. return .processingError
  49. }
  50. }
  51. }