Repository: googleapis/google-cloud-ruby (Ruby)

Issue:
Add GRPC error code to Ruby Cloud error classes for the REST wrapping cases.
Currently the Ruby Cloud errors surface the underlying cause's error code. When they wrap HTTP error there is no `code` (there is an http status code in `status_code`). We should add the corresponding GRPC error code directly to the classes.



Fix (patch):
diff --git a/google-cloud-errors/lib/google/cloud/errors.rb b/google-cloud-errors/lib/google/cloud/errors.rb
index 2d28f158bad3..0f87234f15db 100644
--- a/google-cloud-errors/lib/google/cloud/errors.rb
+++ b/google-cloud-errors/lib/google/cloud/errors.rb
@@ -231,6 +231,13 @@ def self.gapi_error_class_for http_status_code
     ##
     # Canceled indicates the operation was cancelled (typically by the caller).
     class CanceledError < Error
+      ##
+      # gRPC error code for CANCELLED
+      #
+      # @return [Integer]
+      def code
+        1
+      end
     end
 
     ##
@@ -240,6 +247,13 @@ class CanceledError < Error
     # errors raised by APIs that do not return enough error information
     # may be converted to this error.
     class UnknownError < Error
+      ##
+      # gRPC error code for UNKNOWN
+      #
+      # @return [Integer]
+      def code
+        2
+      end
     end
 
     ##
@@ -248,6 +262,13 @@ class UnknownError < Error
     # that are problematic regardless of the state of the system
     # (e.g., a malformed file name).
     class InvalidArgumentError < Error
+      ##
+      # gRPC error code for INVALID_ARGUMENT
+      #
+      # @return [Integer]
+      def code
+        3
+      end
     end
 
     ##
@@ -257,18 +278,39 @@ class InvalidArgumentError < Error
     # example, a successful response from a server could have been delayed
     # long enough for the deadline to expire.
     class DeadlineExceededError < Error
+      ##
+      # gRPC error code for DEADLINE_EXCEEDED
+      #
+      # @return [Integer]
+      def code
+        4
+      end
     end
 
     ##
     # NotFound means some requested entity (e.g., file or directory) was
     # not found.
     class NotFoundError < Error
+      ##
+      # gRPC error code for NOT_FOUND
+      #
+      # @return [Integer]
+      def code
+        5
+      end
     end
 
     ##
     # AlreadyExists means an attempt to create an entity failed because one
     # already exists.
     class AlreadyExistsError < Error
+      ##
+      # gRPC error code for ALREADY_EXISTS
+      #
+      # @return [Integer]
+      def code
+        6
+      end
     end
 
     ##
@@ -279,12 +321,26 @@ class AlreadyExistsError < Error
     # used if the caller cannot be identified (use Unauthenticated
     # instead for those errors).
     class PermissionDeniedError < Error
+      ##
+      # gRPC error code for PERMISSION_DENIED
+      #
+      # @return [Integer]
+      def code
+        7
+      end
     end
 
     ##
     # ResourceExhausted indicates some resource has been exhausted, perhaps
     # a per-user quota, or perhaps the entire file system is out of space.
     class ResourceExhaustedError < Error
+      ##
+      # gRPC error code for RESOURCE_EXHAUSTED
+      #
+      # @return [Integer]
+      def code
+        8
+      end
     end
 
     ##
@@ -308,6 +364,13 @@ class ResourceExhaustedError < Error
     #      server does not match the condition. E.g., conflicting
     #      read-modify-write on the same resource.
     class FailedPreconditionError < Error
+      ##
+      # gRPC error code for FAILED_PRECONDITION
+      #
+      # @return [Integer]
+      def code
+        9
+      end
     end
 
     ##
@@ -318,6 +381,13 @@ class FailedPreconditionError < Error
     # See litmus test above for deciding between FailedPrecondition,
     # Aborted, and Unavailable.
     class AbortedError < Error
+      ##
+      # gRPC error code for ABORTED
+      #
+      # @return [Integer]
+      def code
+        10
+      end
     end
 
     ##
@@ -337,12 +407,26 @@ class AbortedError < Error
     # a space can easily look for an OutOfRange error to detect when
     # they are done.
     class OutOfRangeError < Error
+      ##
+      # gRPC error code for OUT_OF_RANGE
+      #
+      # @return [Integer]
+      def code
+        11
+      end
     end
 
     ##
     # Unimplemented indicates operation is not implemented or not
     # supported/enabled in this service.
     class UnimplementedError < Error
+      ##
+      # gRPC error code for UNIMPLEMENTED
+      #
+      # @return [Integer]
+      def code
+        12
+      end
     end
 
     ##
@@ -350,6 +434,13 @@ class UnimplementedError < Error
     # system has been broken.  If you see one of these errors,
     # something is very broken.
     class InternalError < Error
+      ##
+      # gRPC error code for INTERNAL
+      #
+      # @return [Integer]
+      def code
+        13
+      end
     end
 
     ##
@@ -360,17 +451,38 @@ class InternalError < Error
     # See litmus test above for deciding between FailedPrecondition,
     # Aborted, and Unavailable.
     class UnavailableError < Error
+      ##
+      # gRPC error code for UNAVAILABLE
+      #
+      # @return [Integer]
+      def code
+        14
+      end
     end
 
     ##
     # DataLoss indicates unrecoverable data loss or corruption.
     class DataLossError < Error
+      ##
+      # gRPC error code for DATA_LOSS
+      #
+      # @return [Integer]
+      def code
+        15
+      end
     end
 
     ##
     # Unauthenticated indicates the request does not have valid
     # authentication credentials for the operation.
     class UnauthenticatedError < Error
+      ##
+      # gRPC error code for UNAUTHENTICATED
+      #
+      # @return [Integer]
+      def code
+        16
+      end
     end
   end
 end