Class: BulkOps::Error

Inherits:
Object
  • Object
show all
Defined in:
lib/bulk_ops/error.rb

Constant Summary collapse

MAX_ERROR =
5000
MAX_ERROR_SHORT =
50

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type:, row_number: nil, object_id: nil, message: nil, options_name: nil, option_values: nil, field: nil, url: nil, file: nil) ⇒ Error

Returns a new instance of Error.



7
8
9
10
11
12
13
14
15
16
17
# File 'lib/bulk_ops/error.rb', line 7

def initialize type:, row_number: nil, object_id: nil, message: nil, options_name: nil, option_values: nil, field: nil, url: nil , file: nil
  @type = type
  @row_number = row_number
  @object_id = object_id
  @message = message
  @option_name = option_name
  @option_values = option_values
  @field = field
  @file = file
  @url = url
end

Instance Attribute Details

#fieldObject

Returns the value of attribute field.



2
3
4
# File 'lib/bulk_ops/error.rb', line 2

def field
  @field
end

#fileObject

Returns the value of attribute file.



2
3
4
# File 'lib/bulk_ops/error.rb', line 2

def file
  @file
end

#messageObject

Returns the value of attribute message.



2
3
4
# File 'lib/bulk_ops/error.rb', line 2

def message
  @message
end

#object_idObject

Returns the value of attribute object_id.



2
3
4
# File 'lib/bulk_ops/error.rb', line 2

def object_id
  @object_id
end

#option_nameObject

Returns the value of attribute option_name.



2
3
4
# File 'lib/bulk_ops/error.rb', line 2

def option_name
  @option_name
end

#option_valuesObject

Returns the value of attribute option_values.



2
3
4
# File 'lib/bulk_ops/error.rb', line 2

def option_values
  @option_values
end

#row_numberObject

Returns the value of attribute row_number.



2
3
4
# File 'lib/bulk_ops/error.rb', line 2

def row_number
  @row_number
end

#typeObject

Returns the value of attribute type.



2
3
4
# File 'lib/bulk_ops/error.rb', line 2

def type
  @type
end

#urlObject

Returns the value of attribute url.



2
3
4
# File 'lib/bulk_ops/error.rb', line 2

def url
  @url
end

Class Method Details

.error_message(type, errors, short = false) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/bulk_ops/error.rb', line 43

def self.error_message type, errors, short=false
  max_error = short ? MAX_ERROR_SHORT : MAX_ERROR
  case type
  when :mismatched_auth_terms
    message = "\n-- Controlled Authority IDs and Labels don't match -- \n"
    message += "The operation is set to create an error if the provided URLs for controlled authority terms do not resolve to the provided labels.\n"
    if errors.count < max_error
      message += "The following rows were affected:\n"
      message += errors.map{|error| error.row_number}.join(",")+"\n"
    else
      message += "#{errors.count} rows were affected. An example is row # #{errors.first.row_number}.\n"
    end
  when :upload_error
    message = "\n-- Errors uploading files -- \n"
    message += "Your files looked ok when we checked earlier, but we couldn't access them when we were trying to actually start the operation.\n"
    if errors.count < max_error
      message += "The following files were affected:\n"
      message += errors.map{|error| "Row #{row_number}, Filename: #{error.file}"}.join("\n")+"\n" 
    else
      message += "#{errors.count} rows were affected. An example is row # #{errors.first.row_number} with file #{errors.first.file}.\n"
    end

  when :no_work_id_field
    message = "\n-- Cannot find work id field in spreadsheet -- \n"
    message += "We were trying to start your operation, but could find find the work id for #{errors.count} different rows of the spreadsheet.\n"
    message += "Check your spreadsheet and try again.\n"
    message += errors.map{|arg| "  #{error.object_id || 'new work'}: #{error.message}"}.join("\n") + "\n"
  when :job_failure
    message = "\n-- Jobs Failed -- \n:"
    message += errors.map{|arg| "Error message operating on #{error.object_id || 'new work'}: #{error.message}"}.join("\n") + "\n"
  when :missing_required_option 
    message = "\n-- Errors in configuration file -- \nMissing required option(s):"
    message += errors.map{|arg| error.option_name}.join(", ") + "\n"

  when :invalid_config_value 
    message = "\n-- Errors in configuration file values --\n" 
    errors.each do |error|
      message += "Unacceptable value for #{error.option_name}. Acceptable values include: #{error.option_values}\n"
    end

  when :cannot_get_headers 
    message += "\n-- Error Retrieving Field Headers --\n"
    message += "We cannot retrieve the column headers from metadata spreadsheet on github,\nwhich define the fields for the metadata below.\nEither the connection to github is failing, \nor the metadata spreadsheet on this branch is not properly formatted.\n"

  when :bad_header 
    message =  "\n-- Error interpreting column header(s) --\n"
    message += "We cannot interpret all of the headers from your metadata spreadsheet. \nSpecifically, the following headers did not make sense to us:\n"
    message += errors.map{|error| error.field}.join(", ")+"\n"

  when :cannot_retrieve_label 
    message = "\n-- Errors Retrieving Remote Labels --\n"
    urls = errors.map{|error| error.url}.uniq
    if urls.count < max_error
      urls.each do |url|
        url_errors = errors.select{|er| er.url == url}
        message +=  "Error retrieving label for remote url #{url}. \nThis url appears in #{url_errors.count} instances in the spreadsheet.\n"
        message += "The affected rows are listed here:\n"
        message += url_errors.map{|er| er.row_number}.compact.join('\n')+"\n"
      end
    else
      message += "There were #{urls.count} different URLs in the spreadsheet that we couldn't retrieve labels for,\n making a total of #{errors.count} url related errors.\n These are too many to list, but an example is #{errors.first.url}\n in row #{errors.first.row_number}.\n"
    end

  when :cannot_retrieve_url
    message = "\n-- Errors Retrieving Remote URLs --\n"
    urls = errors.map{|error| error.url}.uniq
    if urls.count < max_error
      urls.each do |url|
        url_errors = errors.select{|er| er.url == url}
        message +=  "Error retrieving URL for remote authority term #{url}. \nThis term appears in #{url_errors.count} instances in the spreadsheet.\n"
        message += "The affected rows are listed here:\n"
        message += url_errors.map{|er| er.row_number}.compact.join('\n')+"\n"
      end
    else
      message += "There were #{urls.count} different controlled vocab terms in the spreadsheet that we couldn't retrieve or create URLs for,\n making a total of #{errors.count} controlled term related errors.\n These are too many to list, but an example is #{errors.first.url}\n in row #{errors.first.row_number}.\n"
    end

  when :bad_object_reference 
    message = "\n-- Error: bad object reference --\n" 
    message += "We enountered #{errors.count} problems resolving object references.\n"
    if errors.count < max_error
       message += "The row numbers with problems were:\n"
       message += errors.map{|er| "row number #{er.row_number} references the object #{er.object_id}"}.join("\n")
    else
       message += "For example, row number #{errors.first.row_number} references an object identified by #{errors.first.object_id}, which we cannot find."
    end
            
  when :cannot_find_file
    message = "\n-- Missing File Errors --\n "
    message += "We couldn't find the files listed on #{errors.count} rows.\n"
    if errors.count < max_error
      message += "Missing filenames:\n"
      message += errors.map{|er| er.file}.join("\n")
    else
      message += "An example of a missing filename is: #{errors.first.file}\n"
    end
    
 when :relationship_error
    message = "\n-- Errors resolving relationships --\n "
    message += "There were issues resolving #{errors.count} relationships.\n"
    if errors.count < max_error
      message += "errors:\n"
      message += errors.map{|er| "Row #{er.row_number}, relationship ##{er.object_id}: #{er.message}"}.join("\n")
    else
      message += "An example of an error is: Row #{er.first.row_number}, relationship ##{er.first.object_id}: #{er.first.message}\n"
    end
    
  when :ingest_failure
    message = "\n-- Ingested File is Broken or Missing --\n "
    message += "After the ingest completed, we had issues finding and re-saving the ingested works associated with #{errors.count} rows.\n"
    if errors.count < max_error
      message += "Problem rows:\n"
      message += errors.map{|er| "#{er.row_number} - proxy ##{er.object_id}"}.join("\n")
    else
      message += "An example of a failed ingest is row #{errors.first.row_number} with work proxy #{errors.first.object_id} \n"
    end

  when :id_not_unique
    message = "\n-- Multiple works shared a supposedly unique identifier, and we don't know which one to edit --\n "
    if errors.count < max_error
      message += "Problem rows:\n"
      message += errors.map{|er| "#{er.row_number} - proxy ##{er.object_id} - #{er.options_name}: #{er.option_values}"}.join("\n")
    else
      message += "An example of a row that identifies multiple works is #{errors.first.row_number} with work proxy #{errors.first.object_id} using the identifier:  #{er.options_name} - #{er.option_values} \n"
    end

  else
    message = "\n-- There were other errors of an unrecognized type. Check the application logs --\n "      
  end
  return message
end

.write_errors!(errors, git) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/bulk_ops/error.rb', line 19

def self.write_errors! errors, git
  return false if errors.blank?
  error_file_name = "error_log_#{DateTime.now.strftime("%F-%H%M%p")}.log"

  error_hash = {}

  errors.sort!{|x,y| x.type <=> y.type}
  error_types = errors.map{|error| error.type}.uniq

  #write errors to error file
  error_file = Tempfile.new(error_file_name)
  error_types.each do |error_type|
    typed_errors = errors.select{|er| er.type == error_type}
    next if typed_errors.blank?
    message = self.error_message(error_type, typed_errors)
    puts "Error message: #{message}"
    error_file.write(message)
  end
  error_file.close
  git.add_file error_file.path, File.join("errors", error_file_name)
  error_file.unlink
  return error_file_name
end