Class: PeakFlowUtils::Notifier
- Inherits:
-
Object
- Object
- PeakFlowUtils::Notifier
- Defined in:
- lib/peak_flow_utils/notifier.rb
Defined Under Namespace
Classes: FailedToReportError, NotConfiguredError, NotifyMessageError
Constant Summary collapse
- CAPTURED_PARAMETERS_INSTANCE_VARIABLE =
:@peak_flow_utils_captured_parameters
Instance Attribute Summary collapse
-
#auth_token ⇒ Object
readonly
Returns the value of attribute auth_token.
-
#mutex ⇒ Object
readonly
Returns the value of attribute mutex.
-
#parameters ⇒ Object
readonly
Returns the value of attribute parameters.
Class Method Summary collapse
- .configure(auth_token:) ⇒ Object
-
.current ⇒ Object
rubocop:disable Style/TrivialAccessors.
- .notify(*args, **kwargs) ⇒ Object
- .notify_message(message) ⇒ Object
- .reset_parameters ⇒ Object
- .with_parameters(parameters) ⇒ Object
Instance Method Summary collapse
- #capture_parameters_for_error(error) ⇒ Object
- #captured_parameters_for_error(error) ⇒ Object
- #current_parameters(error: nil, parameters: nil) ⇒ Object
- #current_parameters_hashes ⇒ Object
- #error_message_from_response(response) ⇒ Object
-
#initialize(auth_token:) ⇒ Notifier
constructor
A new instance of Notifier.
- #notify(error:, environment: nil, parameters: nil) ⇒ Object
- #notify_message(message) ⇒ Object
- #on_notify(&blk) ⇒ Object
- #send_notify_request(data:, uri:) ⇒ Object
Constructor Details
#initialize(auth_token:) ⇒ Notifier
Returns a new instance of Notifier.
61 62 63 64 65 66 |
# File 'lib/peak_flow_utils/notifier.rb', line 61 def initialize(auth_token:) @auth_token = auth_token @mutex = ::Mutex.new @on_notify_callbacks = [] @parameters = ::PeakFlowUtils::InheritedLocalVar.new({}) end |
Instance Attribute Details
#auth_token ⇒ Object (readonly)
Returns the value of attribute auth_token.
8 9 10 |
# File 'lib/peak_flow_utils/notifier.rb', line 8 def auth_token @auth_token end |
#mutex ⇒ Object (readonly)
Returns the value of attribute mutex.
8 9 10 |
# File 'lib/peak_flow_utils/notifier.rb', line 8 def mutex @mutex end |
#parameters ⇒ Object (readonly)
Returns the value of attribute parameters.
8 9 10 |
# File 'lib/peak_flow_utils/notifier.rb', line 8 def parameters @parameters end |
Class Method Details
.configure(auth_token:) ⇒ Object
10 11 12 |
# File 'lib/peak_flow_utils/notifier.rb', line 10 def self.configure(auth_token:) @current = PeakFlowUtils::Notifier.new(auth_token: auth_token) end |
.current ⇒ Object
rubocop:disable Style/TrivialAccessors
14 15 16 |
# File 'lib/peak_flow_utils/notifier.rb', line 14 def self.current # rubocop:disable Style/TrivialAccessors @current end |
.notify(*args, **kwargs) ⇒ Object
18 19 20 21 22 23 24 25 26 |
# File 'lib/peak_flow_utils/notifier.rb', line 18 def self.notify(*args, **kwargs) if args.any? raise ArgumentError, "unexpected positional arguments" unless args.first.is_a?(Hash) && args.length == 1 kwargs = args.first.merge(kwargs) end PeakFlowUtils::Notifier.current&.notify(**kwargs) end |
.notify_message(message) ⇒ Object
28 29 30 |
# File 'lib/peak_flow_utils/notifier.rb', line 28 def self.(, **) PeakFlowUtils::Notifier.current&.(, **) end |
.reset_parameters ⇒ Object
32 33 34 |
# File 'lib/peak_flow_utils/notifier.rb', line 32 def self.reset_parameters ::PeakFlowUtils::Notifier.current&.instance_variable_set(:@parameters, ::PeakFlowUtils::InheritedLocalVar.new({})) end |
.with_parameters(parameters) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/peak_flow_utils/notifier.rb', line 36 def self.with_parameters(parameters) return yield unless ::PeakFlowUtils::Notifier.current random_id = ::SecureRandom.hex(16) ::PeakFlowUtils::Notifier.current.mutex.synchronize do current_parameters = ::PeakFlowUtils::Notifier.current.parameters.value raise "'parameters' was nil?" if current_parameters.nil? current_parameters[random_id] = parameters end begin yield rescue StandardError => e ::PeakFlowUtils::Notifier.current.capture_parameters_for_error(e) raise ensure ::PeakFlowUtils::Notifier.current.mutex.synchronize do current_parameters = ::PeakFlowUtils::Notifier.current.parameters.value current_parameters.delete(random_id) end end end |
Instance Method Details
#capture_parameters_for_error(error) ⇒ Object
68 69 70 71 72 |
# File 'lib/peak_flow_utils/notifier.rb', line 68 def capture_parameters_for_error(error) return if error.instance_variable_defined?(CAPTURED_PARAMETERS_INSTANCE_VARIABLE) error.instance_variable_set(CAPTURED_PARAMETERS_INSTANCE_VARIABLE, current_parameters) end |
#captured_parameters_for_error(error) ⇒ Object
74 75 76 77 78 |
# File 'lib/peak_flow_utils/notifier.rb', line 74 def captured_parameters_for_error(error) return unless error&.instance_variable_defined?(CAPTURED_PARAMETERS_INSTANCE_VARIABLE) error.instance_variable_get(CAPTURED_PARAMETERS_INSTANCE_VARIABLE) end |
#current_parameters(error: nil, parameters: nil) ⇒ Object
80 81 82 83 84 85 86 87 |
# File 'lib/peak_flow_utils/notifier.rb', line 80 def current_parameters(error: nil, parameters: nil) hashes = current_parameters_hashes captured_parameters = captured_parameters_for_error(error) hashes << captured_parameters if captured_parameters hashes << parameters if parameters ::PeakFlowUtils::DeepMerger.execute!(hashes: hashes) end |
#current_parameters_hashes ⇒ Object
89 90 91 |
# File 'lib/peak_flow_utils/notifier.rb', line 89 def current_parameters_hashes parameters.value.values end |
#error_message_from_response(response) ⇒ Object
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/peak_flow_utils/notifier.rb', line 93 def (response) = "Couldn't report error to Peakflow (code #{response.code})" if response["content-type"]&.starts_with?("application/json") response_data = ::JSON.parse(response.body) << ": #{response_data.fetch("errors").join(". ")}" if response_data["errors"] end end |
#notify(error:, environment: nil, parameters: nil) ⇒ Object
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/peak_flow_utils/notifier.rb', line 104 def notify(error:, environment: nil, parameters: nil) error = normalize_error(error, fallback_backtrace: caller(2)) error_parser = ::PeakFlowUtils::NotifierErrorParser.new( backtrace: error.backtrace, environment: environment, error: error ) merged_parameters = current_parameters(error: error, parameters: parameters) uri = URI("https://www.peakflow.io/errors/reports") @on_notify_callbacks.each do |on_notify_callback| on_notify_callback.call(parameters: merged_parameters) end data = { auth_token: auth_token, error: { backtrace: error.backtrace, environment: error_parser.cleaned_environment, error_class: error.class.name, file_path: error_parser.file_path, line_number: error_parser.line_number, message: error., parameters: merged_parameters, remote_ip: error_parser.remote_ip, url: error_parser.url, user_agent: error_parser.user_agent } } send_notify_request(data: PeakFlowUtils::ParseJson.new(data).parse, uri: uri) end |
#notify_message(message) ⇒ Object
139 140 141 142 143 |
# File 'lib/peak_flow_utils/notifier.rb', line 139 def (, **) raise NotifyMessageError, rescue NotifyMessageError => e notify(error: e, **) end |
#on_notify(&blk) ⇒ Object
145 146 147 |
# File 'lib/peak_flow_utils/notifier.rb', line 145 def on_notify(&blk) @on_notify_callbacks << blk end |
#send_notify_request(data:, uri:) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/peak_flow_utils/notifier.rb', line 149 def send_notify_request(data:, uri:) https = ::Net::HTTP.new(uri.host, uri.port) https.use_ssl = true request = ::Net::HTTP::Post.new(uri.path) request["Content-Type"] = "application/json" request.body = ::JSON.generate(data) response = https.request(request) raise FailedToReportError, (response) unless response.code == "200" response_data = ::JSON.parse(response.body) # Data not always present so dont use fetch ::PeakFlowUtils::NotifierResponse.new( bug_report_id: response_data["bug_report_id"], bug_report_instance_id: response_data["bug_report_instance_id"], project_id: response_data["project_id"], project_slug: response_data["project_slug"], url: response_data["url"] ) end |