Browse Source

Don't fail on cancellation (#1415)

Motivation:

Cancellation should not throw if the RPC has already been cancelled.

Modifications:

- Don't fail a cancellation promise if the call has not yet been started
  or has already been cancelled.

Result:

Cancellation does not fail.
George Barnett 3 years ago
parent
commit
2d4b290874

+ 2 - 4
Sources/GRPC/ClientCalls/Call.swift

@@ -308,10 +308,8 @@ extension Call {
 
     switch self._state {
     case .idle:
-      // This is weird: does it make sense to cancel before invoking it?
-      let error = GRPCError.InvalidState("Call must be invoked before cancelling it")
-      promise?.fail(error)
-      self.channelPromise?.fail(error)
+      promise?.succeed(())
+      self.channelPromise?.fail(GRPCStatus(code: .cancelled))
 
     case let .invoked(transport):
       transport.cancel(promise: promise)

+ 1 - 1
Sources/GRPC/Interceptor/ClientTransport.swift

@@ -249,7 +249,7 @@ extension ClientTransport {
       self.channelPromise?.fail(error)
       promise?.succeed(())
     } else {
-      promise?.fail(GRPCError.AlreadyComplete())
+      promise?.succeed(())
     }
   }
 }

+ 1 - 1
Tests/GRPCTests/ClientCallTests.swift

@@ -183,7 +183,7 @@ class ClientCallTests: GRPCTestCase {
 
   func testCancelBeforeInvoke() throws {
     let get = self.get()
-    assertThat(try get.cancel().wait(), .throws())
+    XCTAssertNoThrow(try get.cancel().wait())
   }
 
   func testCancelMidRPC() throws {