def construct_error_details_map_grpc(gax_error)
      return {} unless @partial_success
      error_details_map = Hash.new { |h, k| h[k] = [] }

      error_details = ensure_array(gax_error.status_details)
      raise JSON::ParserError, 'The error details are empty.' if
        error_details.empty?
      raise JSON::ParserError, 'No partial error info in error details.' unless
        error_details[0].is_a?(
          Google::Logging::V2::WriteLogEntriesPartialErrors)
      log_entry_errors = ensure_hash(error_details[0].log_entry_errors)
      log_entry_errors.each do |index, log_entry_error|
        error_key = [log_entry_error[:code], log_entry_error[:message]].freeze
        error_details_map[error_key] << index
      end
      error_details_map
    rescue JSON::ParserError => e
      @log.warn 'Failed to extract log entry errors from the error details:' \
                " #{gax_error.details.inspect}.", error: e
      {}
    end
def construct_error_details_map_grpc(gax_error)
      return {} unless @partial_success
      error_details_map = Hash.new { |h, k| h[k] = [] }

      error_details = ensure_array(gax_error.status_details)
      raise JSON::ParserError, 'The error details are empty.' if
        error_details.empty?
      raise JSON::ParserError, 'No partial error info in error details.' unless
        error_details[0].is_a?(
          Google::Logging::V2::WriteLogEntriesPartialErrors)
      log_entry_errors = ensure_hash(error_details[0].log_entry_errors)
      log_entry_errors.each do |index, log_entry_error|
        error_key = [log_entry_error[:code], log_entry_error[:message]].freeze
        error_details_map[error_key] << index
      end
      error_details_map
    rescue JSON::ParserError => e
      @log.warn 'Failed to extract log entry errors from the error details:' \
                " #{gax_error.details.inspect}.", error: e
      {}
    end
Extract a map of error details from a potentially partially successful
 gRPC request. Return an empty map if @partial_success is not enabled.

 The keys in this map are [error_code, error_message] pairs, and the values
 are a list of indexes of log entries that failed due to this error.

 A sample error looks like:
 <Google::Gax::RetryError:
   message: 'GaxError Exception occurred in retry method that was not class
             ified as transient, caused by 7:User not authorized.',
   details: [
     <Google::Logging::V2::WriteLogEntriesPartialErrors:
       log_entry_errors: {
         0 => <Google::Rpc::Status:
                code: 7,
                message: "User not authorized.",
                details: []>,
         1 => <Google::Rpc::Status:
                code: 3,
                message: "Log name contains illegal character :",
                details: []>,
         3 => <Google::Rpc::Status:
                code: 3,
                message: "Log name contains illegal character :",
                details: []>
       }
     >,
     <Google::Rpc::DebugInfo:
       stack_entries: [],
       detail: "..."
     >
   ]
   cause: <GRPC::PermissionDenied: 7:User not authorized.>
 }

 The ultimate map that is constructed is:
 {
   [7, 'User not authorized.']: [0],
   [3, 'Log name contains illegal character :']: [1, 3]
 }