Module: Jekyll::Algolia::ErrorHandler
- Includes:
- Jekyll::Algolia
- Defined in:
- lib/jekyll/algolia/error_handler.rb
Overview
Catch API errors and display messages
Constant Summary
Constants included from Jekyll::Algolia
MissingCredentialsError, VERSION
Class Method Summary collapse
-
.error_hash(message) ⇒ Object
Public: Parses an Algolia error message into a hash of its content.
-
.identify(error, context = {}) ⇒ Object
Public: Will identify the error and return its internal name.
-
.invalid_credentials?(error, _context = {}) ⇒ Boolean
Public: Check if the credentials are working.
-
.invalid_index_name?(error, _context = {}) ⇒ Boolean
Public: Check if the index name is invalid.
-
.record_too_big_api?(error, _context = {}) ⇒ Boolean
Public: Check if the sent records are not too big.
-
.stop(error, context = {}) ⇒ Object
Public: Stop the execution of the plugin and display if possible a human-readable error message.
-
.too_many_records?(error, _context = {}) ⇒ Boolean
Public: Check if the application has too many records.
-
.unknown_application_id?(error, _context = {}) ⇒ Boolean
Public: Check if the application id is available.
-
.unknown_setting?(error, context = {}) ⇒ Boolean
Public: Check if one of the index settings is invalid.
Methods included from Jekyll::Algolia
init, load_overwrites, run, site
Class Method Details
.error_hash(message) ⇒ Object
Public: Parses an Algolia error message into a hash of its content
message - The raw message as returned by the API
Returns a hash of all parts of the message, to be more easily consumed by our error matchers
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 |
# File 'lib/jekyll/algolia/error_handler.rb', line 75 def self.error_hash() = .delete("\n") # Ex: Cannot PUT to https://appid.algolia.net/1/indexes/index_name/settings: # {"message":"Invalid Application-ID or API key","status":403} (403) regex = VerEx.new do find 'Cannot ' capture('verb') { word } find ' to ' capture('scheme') { word } find '://' capture('application_id') { word } anything_but '/' find '/' capture('api_version') { digit } find '/' capture('api_section') { word } find '/' capture('index_name') do anything_but('/') end find '/' capture do capture('api_action') { word } maybe '?' capture('query_parameters') do anything_but(':') end end find ': ' capture('json') do find '{' anything_but('}') find '}' end find ' (' capture('http_error') { word } find ')' end matches = regex.match() return false unless matches # Convert matches to a hash hash = {} matches.names.each do |name| hash[name] = matches[name] end hash['api_version'] = hash['api_version'].to_i hash['http_error'] = hash['http_error'].to_i # Merging the JSON key directly in the answer hash = hash.merge(JSON.parse(hash['json'])) hash.delete('json') # Merging the query parameters in the answer CGI.parse(hash['query_parameters']).each do |key, values| hash[key] = values[0] end hash.delete('query_parameters') hash end |
.identify(error, context = {}) ⇒ Object
Public: Will identify the error and return its internal name
error - The caught error context - A hash of additional information that can be passed from the code intercepting the user
It will parse in order all potential known issues until it finds one that matches. Returns false if no match, or a hash of :name and :details further identifying the issue.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/jekyll/algolia/error_handler.rb', line 46 def self.identify(error, context = {}) known_errors = %w[ unknown_application_id invalid_credentials record_too_big_api too_many_records unknown_setting invalid_index_name ] # Checking the errors against our known list known_errors.each do |potential_error| error_check = send("#{potential_error}?", error, context) next if error_check == false return { name: potential_error, details: error_check } end false end |
.invalid_credentials?(error, _context = {}) ⇒ Boolean
Public: Check if the credentials are working
_context - Not used
Application ID and API key submitted don’t match any credentials known
164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/jekyll/algolia/error_handler.rb', line 164 def self.invalid_credentials?(error, _context = {}) details = error_hash(error.) return false if details == false if details['message'] != 'Invalid Application-ID or API key' return false end { 'application_id' => details['application_id'], 'index_name' => Configurator.index_name, 'index_object_ids_name' => Configurator.index_object_ids_name } end |
.invalid_index_name?(error, _context = {}) ⇒ Boolean
Public: Check if the index name is invalid
Some characters are forbidden in index names
232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/jekyll/algolia/error_handler.rb', line 232 def self.invalid_index_name?(error, _context = {}) details = error_hash(error.) return false if details == false = details['message'] return false if !~ /^indexName is not valid.*/ { 'index_name' => Configurator.index_name } end |
.record_too_big_api?(error, _context = {}) ⇒ Boolean
Public: Check if the sent records are not too big
context - list of records sent in the batch
One of the sent record is too big and has been rejected by the API. This should not happen as we proactively check for record size before pushing them. If it still happens it means that the value set in max_record_size is not matching the value in the plan.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/jekyll/algolia/error_handler.rb', line 187 def self.record_too_big_api?(error, _context = {}) details = error_hash(error.) return false if details == false = details['message'] return false if !~ /^Record .* is too big .*/ record_size, = /.*size=(.*) bytes.*/.match().captures record_size_readable = Filesize.from("#{record_size}B").to_s('Kb') max_record_size = Configurator.algolia('max_record_size') { 'record_size' => record_size_readable, 'max_record_size' => max_record_size } end |
.stop(error, context = {}) ⇒ Object
Public: Stop the execution of the plugin and display if possible a human-readable error message
error - The caught error context - A hash of values that will be passed from where the error happened to the display
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/jekyll/algolia/error_handler.rb', line 19 def self.stop(error, context = {}) Logger.verbose("E:[jekyll-algolia] Raw error: #{error}") identified_error = identify(error, context) if identified_error == false Logger.log('E:[jekyll-algolia] Error:') Logger.log("E:#{error}") else Logger.( identified_error[:name], identified_error[:details] ) end exit 1 end |
.too_many_records?(error, _context = {}) ⇒ Boolean
Public: Check if the application has too many records
We’re trying to push too many records and it goes over quota
247 248 249 250 251 252 253 254 255 |
# File 'lib/jekyll/algolia/error_handler.rb', line 247 def self.too_many_records?(error, _context = {}) details = error_hash(error.) return false if details == false = details['message'] return false if !~ /^Record quota exceeded.*/ {} end |
.unknown_application_id?(error, _context = {}) ⇒ Boolean
Public: Check if the application id is available
_context - Not used
If the call to the cluster fails, chances are that the application ID is invalid. As we cannot actually contact the server, the error is raw and does not follow our error spec
146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/jekyll/algolia/error_handler.rb', line 146 def self.unknown_application_id?(error, _context = {}) = error. return false if !~ /^Cannot reach any host/ matches = /.*\((.*)\.algolia.net.*/.match() # The API will browse on APP_ID-dsn, but push/delete on APP_ID only # We need to catch both potential errors app_id = matches[1].gsub(/-dsn$/, '') { 'application_id' => app_id } end |
.unknown_setting?(error, context = {}) ⇒ Boolean
Public: Check if one of the index settings is invalid
context - The settings passed to update the index
The API will block any call that tries to update a setting value that is not available. We’ll tell the user which one so they can fix their issue.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/jekyll/algolia/error_handler.rb', line 211 def self.unknown_setting?(error, context = {}) details = error_hash(error.) return false if details == false = details['message'] return false if !~ /^Invalid object attributes.*/ # Getting the unknown setting name regex = /^Invalid object attributes: (.*) near line.*/ setting_name, = regex.match().captures setting_value = context[:settings][setting_name] { 'setting_name' => setting_name, 'setting_value' => setting_value } end |