mihari 7.0.4 → 7.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5859aa404d85ccc45008979195ace2c4104cc86336b65afacbeece226c7def5
4
- data.tar.gz: 75f6687159420d8f0d7b5f2f13fbab7f523881ad55a66574a7a9ec612cf720ae
3
+ metadata.gz: aca048c797a73db1c57f0a5ad5f29066fbfba69451c71df1a26c3ea57853a1e3
4
+ data.tar.gz: 5ce2d298f325cc9d0ae50a98a6c18a64ec11cc06386504535c8ca647c7c68ad0
5
5
  SHA512:
6
- metadata.gz: 9db820d33af592d9b2953a01e745ce05c3a297a6cbefb409e147fd90ab5d02070722abbba18b3f282bf9abcc1cc85f50d2579ab2774ea26074d74b6aea8d6073
7
- data.tar.gz: 8218aaf062e8ecad9cf01f58188de497ffba135ce42269e7ff87b82d49cf96c0a46c0aa273e752da1f97b288ffead8569fa00c8d6452701273e9694bcf4dba74
6
+ metadata.gz: ac1d6ab49351a2c9c60e703a5fe5fe0f94c84c4294271f297d529a781d3a87a37b515d090a78676bcaf3da225f03617f8900966d108e31557e86319a2407b00b
7
+ data.tar.gz: f5aad0f8648783f4d3c3cc42a087f646358e5e93586cb394a2644e8f6c32a296b3668ea7758348c0dd55d4868527b4aa6a3d774ee113d5a4a14c39ae3ecd2857
@@ -92,7 +92,15 @@ module Mihari
92
92
 
93
93
  return res.recover { [] } if ignore_error?
94
94
 
95
- res.to_result
95
+ result = res.to_result
96
+ return result if result.success?
97
+
98
+ # Wrap failure with AnalyzerError to explicitly name a failed analyzer
99
+ Failure AnalyzerError.new(
100
+ result.failure.message,
101
+ self.class.class_key,
102
+ cause: result.failure
103
+ )
96
104
  end
97
105
 
98
106
  class << self
@@ -41,17 +41,17 @@ module Mihari
41
41
  def safe_execute
42
42
  yield
43
43
  rescue StandardError => e
44
- err = unwrap_error(e)
44
+ error = unwrap_error(e)
45
45
 
46
- raise err if options["debug"]
46
+ raise error if options["debug"]
47
47
 
48
- case err
49
- when ValidationError
50
- warn JSON.pretty_generate(err.errors.to_h)
51
- when StandardError
52
- Sentry.capture_exception(err) if Sentry.initialized?
53
- warn err
54
- end
48
+ data = Entities::ErrorMessage.represent(
49
+ message: error.message,
50
+ detail: error.respond_to?(:detail) ? error.detail : nil
51
+ )
52
+ warn JSON.pretty_generate(data.as_json)
53
+
54
+ Sentry.capture_exception(error) if Sentry.initialized? && !error.is_a?(ValidationError)
55
55
 
56
56
  exit 1
57
57
  end
@@ -52,7 +52,10 @@ module Mihari
52
52
  def search(query, page:, size: PAGE_SIZE)
53
53
  qbase64 = Base64.urlsafe_encode64(query)
54
54
  params = { qbase64: qbase64, size: size, page: page, email: email, key: api_key }.compact
55
- Structs::Fofa::Response.from_dynamic! get_json("/api/v1/search/all", params: params)
55
+ res = Structs::Fofa::Response.from_dynamic!(get_json("/api/v1/search/all", params: params))
56
+ raise ResponseError, res.errmsg if res.error
57
+
58
+ res
56
59
  end
57
60
 
58
61
  #
@@ -17,9 +17,10 @@ module Mihari
17
17
  receiver = err.receiver
18
18
  case receiver
19
19
  when Dry::Monads::Try::Error
20
- receiver.exception
20
+ # Error may be wrapped like Matryoshka
21
+ unwrap_error receiver.exception
21
22
  when Dry::Monads::Failure
22
- receiver.failure
23
+ unwrap_error receiver.failure
23
24
  else
24
25
  err
25
26
  end
@@ -8,35 +8,48 @@ module Mihari
8
8
  module Retriable
9
9
  extend ActiveSupport::Concern
10
10
 
11
- DEFAULT_ON = [
12
- Errno::ECONNRESET,
13
- Errno::ECONNABORTED,
14
- Errno::EPIPE,
11
+ RETRIABLE_ERRORS = [
15
12
  OpenSSL::SSL::SSLError,
16
13
  Timeout::Error,
17
- RetryableError,
18
- NetworkError,
19
- TimeoutError,
20
- StatusCodeError
14
+ ::HTTP::ConnectionError,
15
+ ::HTTP::ResponseError,
16
+ ::HTTP::TimeoutError
21
17
  ].freeze
22
18
 
19
+ DEFAULT_CONDITION = lambda do |error|
20
+ return true if RETRIABLE_ERRORS.any? { |klass| error.is_a? klass }
21
+
22
+ case error
23
+ when StatusCodeError
24
+ error.status_code != 404
25
+ else
26
+ false
27
+ end
28
+ end
29
+
23
30
  #
24
31
  # Retry on error
25
32
  #
26
33
  # @param [Integer] times
27
34
  # @param [Integer] interval
28
35
  # @param [Boolean] exponential_backoff
29
- # @param [Array<StandardError>] on
36
+ # @param [Proc] condition
30
37
  #
31
- def retry_on_error(times: 3, interval: 5, exponential_backoff: true, on: DEFAULT_ON)
38
+ # @param [Object] on
39
+ def retry_on_error(times: 3, interval: 5, exponential_backoff: true, condition: DEFAULT_CONDITION)
32
40
  try = 0
33
41
  begin
34
42
  try += 1
35
43
  yield
36
- rescue *on => e
44
+ rescue StandardError => e
45
+ # Raise error if it's not a retriable error
46
+ raise e unless condition.call(e)
47
+
37
48
  sleep_seconds = exponential_backoff ? interval * (2**(try - 1)) : interval
38
49
  sleep sleep_seconds
39
50
  retry if try < times
51
+
52
+ # Raise error if retry times exceed a given times
40
53
  raise e
41
54
  end
42
55
  end
data/lib/mihari/errors.rb CHANGED
@@ -1,27 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "http"
4
+
3
5
  module Mihari
4
6
  class Error < StandardError; end
5
7
 
6
8
  class ValueError < Error; end
7
9
 
8
- class RetryableError < Error; end
9
-
10
10
  class ConfigurationError < Error; end
11
11
 
12
- class IntegrityError < Error; end
12
+ class ResponseError < Error; end
13
13
 
14
- # errors for HTTP interactions
15
- class HTTPError < Error; end
14
+ class AnalyzerError < Error
15
+ # @return [StandardException, nil]
16
+ attr_reader :cause
16
17
 
17
- class NetworkError < HTTPError; end
18
+ #
19
+ # @param [String] msg
20
+ # @param [String] analyzer
21
+ # @param [StandardException, nil] cause
22
+ #
23
+ def initialize(msg, analyzer, cause: nil)
24
+ super("#{msg} (from #{analyzer})")
25
+
26
+ @cause = cause
27
+ set_backtrace(cause.backtrace) if cause
28
+ end
18
29
 
19
- class TimeoutError < HTTPError; end
30
+ def detail
31
+ return nil unless cause.respond_to?(:detail)
32
+
33
+ cause.detail
34
+ end
35
+ end
36
+
37
+ class IntegrityError < Error; end
20
38
 
21
39
  #
22
40
  # HTTP status code error
23
41
  #
24
- class StatusCodeError < HTTPError
42
+ class StatusCodeError < ::HTTP::Error
25
43
  # @return [Integer]
26
44
  attr_reader :status_code
27
45
 
@@ -39,6 +57,10 @@ module Mihari
39
57
  @status_code = status_code
40
58
  @body = body
41
59
  end
60
+
61
+ def detail
62
+ { status_code: status_code, body: body }
63
+ end
42
64
  end
43
65
 
44
66
  #
@@ -56,5 +78,9 @@ module Mihari
56
78
 
57
79
  @errors = errors
58
80
  end
81
+
82
+ def detail
83
+ errors.to_h
84
+ end
59
85
  end
60
86
  end
data/lib/mihari/http.rb CHANGED
@@ -18,11 +18,6 @@ module Mihari
18
18
  )
19
19
  end
20
20
 
21
- def on_error(_request, error)
22
- raise TimeoutError, error if error.is_a?(::HTTP::TimeoutError)
23
- raise NetworkError, error if error.is_a?(::HTTP::Error)
24
- end
25
-
26
21
  ::HTTP::Options.register_feature(:better_error, self)
27
22
  end
28
23
 
data/lib/mihari/rule.rb CHANGED
@@ -83,6 +83,20 @@ module Mihari
83
83
  data[:data_types]
84
84
  end
85
85
 
86
+ #
87
+ # @return [Date, nil]
88
+ #
89
+ def created_on
90
+ data[:created_on]
91
+ end
92
+
93
+ #
94
+ # @return [Date, nil]
95
+ #
96
+ def updated_on
97
+ data[:updated_on]
98
+ end
99
+
86
100
  #
87
101
  # @return [Array<Mihari::Models::Tag>]
88
102
  #
@@ -279,8 +293,8 @@ module Mihari
279
293
  # data is serialized as JSON so dates (created_on & updated_on) are stringified in there
280
294
  # thus dates & (hash) keys have to be stringified when comparing
281
295
  data.deep_dup.tap do |data|
282
- data[:created_on] = data[:created_on].to_s
283
- data[:updated_on] = data[:updated_on].to_s
296
+ data[:created_on] = created_on.to_s unless created_on.nil?
297
+ data[:updated_on] = updated_on.to_s unless updated_on.nil?
284
298
  end.deep_stringify_keys
285
299
  end
286
300
 
@@ -8,6 +8,10 @@ module Mihari
8
8
  # @return [Boolean]
9
9
  attribute :error, Types::Bool
10
10
 
11
+ # @!attribute [r] errmsg
12
+ # @return [String, nil]
13
+ attribute? :errmsg, Types::String.optional
14
+
11
15
  # @!attribute [r] size
12
16
  # @return [Integer, nil]
13
17
  attribute? :size, Types::Int.optional
@@ -35,6 +39,7 @@ module Mihari
35
39
  def from_dynamic!(d)
36
40
  new(
37
41
  error: d.fetch("error"),
42
+ errmsg: d["errmsg"],
38
43
  size: d["size"],
39
44
  page: d["page"],
40
45
  mode: d["mode"],
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mihari
4
- VERSION = "7.0.4"
4
+ VERSION = "7.0.5"
5
5
  end