From acacd0d6467109e452e7375f662240c26fca004f Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Tue, 29 Nov 2016 23:42:27 -0800
Subject: [PATCH] add factory method to bad status to create correct subclass

---
 src/ruby/lib/grpc/errors.rb        | 43 ++++++++++++++++++++++++++++++
 src/ruby/spec/error_sanity_spec.rb |  8 +++++-
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb
index 022a14b0a5..41c15de1d5 100644
--- a/src/ruby/lib/grpc/errors.rb
+++ b/src/ruby/lib/grpc/errors.rb
@@ -45,6 +45,8 @@ module GRPC
   class BadStatus < StandardError
     attr_reader :code, :details, :metadata
 
+    include GRPC::Core::StatusCodes
+
     # @param code [Numeric] the status code
     # @param details [String] the details of the exception
     # @param metadata [Hash] the error's metadata
@@ -62,6 +64,47 @@ module GRPC
     def to_status
       Struct::Status.new(code, details, @metadata)
     end
+
+    def self.new_status_exception(code, details = 'unkown cause', metadata = {})
+      case code
+      when OK
+	Ok.new(details, metadata)
+      when CANCELLED
+	Cancelled.new(details, metadata)
+      when UNKNOWN
+	Unknown.new(details, metadata)
+      when INVALID_ARGUMENT
+	InvalidArgument.new(details, metadata)
+      when DEADLINE_EXCEEDED
+	DeadlineExceeded.new(details, metadata)
+      when NOT_FOUND
+	NotFound.new(details, metadata)
+      when ALREADY_EXISTS
+	AlreadyExists.new(details, metadata)
+      when PERMISSION_DENIED
+	PermissionDenied.new(details, metadata)
+      when UNAUTHENTICATED
+	Unauthenticated.new(details, metadata)
+      when RESOURCE_EXHAUSTED
+	ResourceExhausted.new(details, metadata)
+      when FAILED_PRECONDITION
+	FailedPrecondition.new(details, metadata)
+      when ABORTED
+	Aborted.new(details, metadata)
+      when OUT_OF_RANGE
+	OutOfRange.new(details, metadata)
+      when UNIMPLEMENTED
+	Unimplemented.new(details, metadata)
+      when INTERNAL
+	Internal.new(details, metadata)
+      when UNAVAILABLE 
+	Unavailable.new(details, metadata)
+      when DATA_LOSS
+	DataLoss.new(details, metadata)
+      else
+        fail 'unknown code'
+      end
+    end
   end
 
   # GRPC status code corresponding to status OK
diff --git a/src/ruby/spec/error_sanity_spec.rb b/src/ruby/spec/error_sanity_spec.rb
index 97712104fe..ca2d80e685 100644
--- a/src/ruby/spec/error_sanity_spec.rb
+++ b/src/ruby/spec/error_sanity_spec.rb
@@ -48,11 +48,17 @@ describe StatusCodes do
 
       error_object = error_class.new
       # check that the code matches the int value of the error's constant
-      expect(error_object.code).to eq(StatusCodes.const_get(status_name))
+      status_code = StatusCodes.const_get(status_name)
+      expect(error_object.code).to eq(status_code)
 
       # check default parameters
       expect(error_object.details).to eq('unknown cause')
       expect(error_object.metadata).to eq({})
+
+      # check that the BadStatus factory for creates the correct
+      # exception too
+      from_factory = GRPC::BadStatus.new_status_exception(status_code)
+      expect(from_factory.is_a?(error_class)).to be(true)
     end
   end
 end
-- 
GitLab