Class: Beowulf::ErrorParser
- Inherits:
-
Object
- Object
- Beowulf::ErrorParser
- Includes:
- Utils
- Defined in:
- lib/beowulf/error_parser.rb
Constant Summary collapse
- REPREPARE_WHITELIST =
[ 'is_canonical( c ): signature is not canonical', 'now < trx.expiration: ' ]
- DUPECHECK =
'(skip & skip_transaction_dupe_check) || trx_idx.indices().get<by_trx_id>().find(trx_id) == trx_idx.indices().get<by_trx_id>().end(): Duplicate transaction check failed'
- REPREPARE_BLACKLIST =
[DUPECHECK]
Instance Attribute Summary collapse
-
#api_method ⇒ Object
readonly
Returns the value of attribute api_method.
-
#api_name ⇒ Object
readonly
Returns the value of attribute api_name.
-
#api_params ⇒ Object
readonly
Returns the value of attribute api_params.
-
#can_reprepare ⇒ Object
(also: #can_reprepare?)
readonly
Returns the value of attribute can_reprepare.
-
#can_retry ⇒ Object
(also: #can_retry?)
readonly
Returns the value of attribute can_retry.
-
#debug ⇒ Object
readonly
Returns the value of attribute debug.
-
#error ⇒ Object
readonly
Returns the value of attribute error.
-
#error_code ⇒ Object
readonly
Returns the value of attribute error_code.
-
#error_message ⇒ Object
readonly
Returns the value of attribute error_message.
-
#expiry ⇒ Object
(also: #expiry?)
readonly
Returns the value of attribute expiry.
-
#node_degraded ⇒ Object
(also: #node_degraded?)
readonly
Returns the value of attribute node_degraded.
-
#response ⇒ Object
readonly
Returns the value of attribute response.
-
#trx_id ⇒ Object
readonly
Returns the value of attribute trx_id.
Instance Method Summary collapse
- #coerce_backtrace ⇒ Object
- #error_match?(matches) ⇒ Boolean
-
#initialize(response) ⇒ ErrorParser
constructor
A new instance of ErrorParser.
- #inspect ⇒ Object
- #parse_error_response ⇒ Object
- #to_s ⇒ Object
Methods included from Utils
#extract_signatures, #hexlify, #pakArr, #pakC, #pakHash, #pakI, #pakL!, #pakPubKey, #pakQ, #pakS, #pakStr, #pakc, #pakq, #paks, #send_log, #unhexlify, #varint, #warning
Constructor Details
#initialize(response) ⇒ ErrorParser
Returns a new instance of ErrorParser.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/beowulf/error_parser.rb', line 23 def initialize(response) @response = response @error = nil @error_code = nil @error_message = nil @api_name = nil @api_method = nil @api_params = nil @expiry = nil @can_retry = nil @can_reprepare = nil @trx_id = nil @debug = nil parse_error_response end |
Instance Attribute Details
#api_method ⇒ Object (readonly)
Returns the value of attribute api_method.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def api_method @api_method end |
#api_name ⇒ Object (readonly)
Returns the value of attribute api_name.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def api_name @api_name end |
#api_params ⇒ Object (readonly)
Returns the value of attribute api_params.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def api_params @api_params end |
#can_reprepare ⇒ Object (readonly) Also known as: can_reprepare?
Returns the value of attribute can_reprepare.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def can_reprepare @can_reprepare end |
#can_retry ⇒ Object (readonly) Also known as: can_retry?
Returns the value of attribute can_retry.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def can_retry @can_retry end |
#debug ⇒ Object (readonly)
Returns the value of attribute debug.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def debug @debug end |
#error ⇒ Object (readonly)
Returns the value of attribute error.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def error @error end |
#error_code ⇒ Object (readonly)
Returns the value of attribute error_code.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def error_code @error_code end |
#error_message ⇒ Object (readonly)
Returns the value of attribute error_message.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def @error_message end |
#expiry ⇒ Object (readonly) Also known as: expiry?
Returns the value of attribute expiry.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def expiry @expiry end |
#node_degraded ⇒ Object (readonly) Also known as: node_degraded?
Returns the value of attribute node_degraded.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def node_degraded @node_degraded end |
#response ⇒ Object (readonly)
Returns the value of attribute response.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def response @response end |
#trx_id ⇒ Object (readonly)
Returns the value of attribute trx_id.
5 6 7 |
# File 'lib/beowulf/error_parser.rb', line 5 def trx_id @trx_id end |
Instance Method Details
#coerce_backtrace ⇒ Object
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/beowulf/error_parser.rb', line 169 def coerce_backtrace can_retry = false case @error['code'] when -32003 any_of = [ 'Internal Error"', '_api_plugin not enabled.' ] can_retry = error_match?('Unable to acquire database lock') if !can_retry && error_match?(any_of) can_retry = true @node_degraded = true else @node_degraded = false end when -32002 can_retry = @node_degraded = error_match?('Could not find API') when 1 can_retry = @node_degraded = error_match?('no method with name \'condenser_api') end can_retry end |
#error_match?(matches) ⇒ Boolean
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/beowulf/error_parser.rb', line 196 def error_match?(matches) matches = [matches].flatten any = matches.map do |match| case match when String @error['message'] && @error['message'].include?(match) when ::Array if @error['message'] match.map { |m| m.include?(match) }.include? true else false end else; false end end any.include?(true) end |
#inspect ⇒ Object
224 225 226 |
# File 'lib/beowulf/error_parser.rb', line 224 def inspect "#<#{self.class.name} [#{to_s}]>" end |
#parse_error_response ⇒ Object
42 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 |
# File 'lib/beowulf/error_parser.rb', line 42 def parse_error_response if response.nil? @expiry = false @can_retry = false @can_reprepare = false return end @response = JSON[response] if response.class == String @error = if !!@response['error'] response['error'] else response end begin if !!@error['data'] # These are, by far, the more interesting errors, so we try to pull # them out first, if possible. @error_code = @error['data']['code'] stacks = @error['data']['stack'] stack_formats = nil @error_message = if !!stacks stack_formats = stacks.map { |s| s['format'] } stack_datum = stacks.map { |s| s['data'] } data_call_method = stack_datum.find { |data| data['call.method'] == 'call' } data_name = stack_datum.find { |data| !!data['name'] } # See if we can recover a transaction id out of this hot mess. data_trx_ix = stack_datum.find { |data| !!data['trx_ix'] } @trx_id = data_trx_ix['trx_ix'] if !!data_trx_ix stack_formats.reject(&:empty?).join('; ') else @error_code ||= @error['code'] @error['message'] end @api_name, @api_method, @api_params = if !!data_call_method @api_name = data_call_method['call.params'] end else @error_code = @error['code'] @error_message = @error['message'] @expiry = false @can_retry = false @can_reprepare = false end case @error_code when -32603 if error_match?('Internal Error') @expiry = false @can_retry = true @can_reprepare = true end when -32003 if error_match?('Unable to acquire database lock') @expiry = false @can_retry = true @can_reprepare = true end when -32000 @expiry = false @can_retry = coerce_backtrace @can_reprepare = if @api_name == 'network_broadcast_api' error_match(REPREPARE_WHITELIST) else false end when 10 @expiry = false @can_retry = coerce_backtrace @can_reprepare = !!stack_formats && (stack_formats & REPREPARE_WHITELIST).any? when 13 @error_message = @error['data']['message'] @expiry = false @can_retry = false @can_reprepare = false when 3030000 @error_message = @error['data']['message'] @expiry = false @can_retry = false @can_reprepare = false when 4030100 # Code 4030100 is "transaction_expiration_exception: transaction # expiration exception". If we assume the expiration was valid, the # node might be bad and needs to be dropped. @expiry = true @can_retry = true @can_reprepare = false when 4030200 # Code 4030200 is "transaction tapos exception". They are recoverable # if the transaction hasn't expired yet. A tapos exception can be # retried in situations where the node is behind and the tapos is # based on a block the node doesn't know about yet. @expiry = false @can_retry = true # Allow fall back to reprepare if retry fails. @can_reprepare = true else @expiry = false @can_retry = false @can_reprepare = false end rescue => e if defined? ap if ENV['DEBUG'] == 'true' ap error_parser_exception: e, original_response: response, backtrace: e.backtrace else ap error_parser_exception: e, original_response: response end end @expiry = false @can_retry = false @can_reprepare = false end end |
#to_s ⇒ Object
216 217 218 219 220 221 222 |
# File 'lib/beowulf/error_parser.rb', line 216 def to_s if !! && !.empty? "#{error_code}: #{}" else error_code.to_s end end |