module Eco module API class Session class Batch # Helper object linked to a `batch status` class Errors # @attr_reader status [Eco::API::Session::Batch::Status] `batch status` this `Errors` object is associated to. attr_reader :status # @param status [Eco::API::Session::Batch::Status] `batch status` this `Errors` object is associated to. def initialize(status:) "Expected Batch::Status as root. Given: #{status.class}" unless status.is_a?(Eco::API::Session::Batch::Status) @status = status end # @see [Eco::API::Session::Batch::Status#queue] def queue status.queue end # @see [Eco::API::Session::Batch::Status#method] def method status.method end # @see [Eco::API::Session::Batch::Status#to_index] def to_index(*args) status.to_index(*args) end # @return [Eco::API::Session] currently active `session` def session status.session end def logger status.logger end # Was there any **error** as a result of this batch? # @return [Boolean] `true` if any of the queried _entries_ got an unsuccessful `Ecoportal::API::Common::BatchResponse` def any? queue.any? {|query| !status[query].success?} end # Input entries that got launched against the server. # @raise [Exception] if there are elements of the final `queue` that did not get response # @note discards those that did not get _response_ from the Server (so those that were not queried) # - please, observe that this can only happen if there were repeated entries in the `source_queue` # @return [Array, Array, Array] def entries queue.each_with_index.map do |query, i| unless response = status[i] msg = "Error: query with no response. You might have duplicated entries in your queue.\n" msg += "Queue length: #{queue.length}; Queue elements class: #{queue.first.class}\n" msg += "Query with no response. Person: #{person_ref(query)}\n" queue.map do |entry| if [:id, :external_id, :email].any? {|attr| (v = get_attr(entry, attr)) && v == get_attr(query, attr)} msg += "It could be this peson entry (idx: #{to_index(entry)}): #{person_ref(entry)}\n" end end raise msg end response.success? ? nil : query end.compact end def errors entries.each_with_object([]) do |entry, arr| if errs = status[entry].body["errors"] errs.each do |msg| arr.push({ type: klass = Eco::API::Error.get_type(msg), err: klass.new(err_msg: msg, entry: entry, session: session), entry: entry }) end end end end def by_type errors.group_by do |h| h[:type] end.transform_values do |arr| arr.map {|h| h[:entry]} end end def count entries.length end def str(key) msg = "" unless status.success?(key) i = to_index(key) entry = queue.to_a[i] response = status[i] msg = "Error #{response.status}: #{response.body}\n" msg += "-- Failed to batch #{method} (entry #{i+1}). Person: #{person_ref(entry)}" end msg end def strs by_type.values.flatten(1).each_with_object([]) do |query, msgs| msgs.push(str(query)) end end def print_one(key) unless status.success?(key) logger.error(str(key)) end end def print msgs = strs if msgs.length > 0 logger.info() logger.error("There were #{msgs.length} errors:\n" + msgs.join("\n")) else logger.info("There were no errors for the current batch '#{method}'!! ;)") end end private def person_ref(entry) "(id: '#{get_attr(entry, :id)}') '#{get_attr(entry, :name)}' ('#{get_attr(entry, :external_id)}': '#{get_attr(entry, :email)}')" end def get_attr(entry, attr) if entry.respond_to?(attr.to_sym) entry.public_send(attr.to_sym) elsif entry.is_a?(Hash) entry["#{attr}"] end end end end end end end