Module: FulfilApi::Error::Notifiable

Extended by:
ActiveSupport::Concern
Included in:
FulfilApi::Error
Defined in:
lib/fulfil_api/error/notifiable.rb

Overview

Note:

A subscriber must not change the behaviour of the application it observes. An exception raised by a subscriber is therefore swallowed and reported on $stderr rather than allowed to replace the FulfilApi::Error on its way up.

The Notifiable publishes an ActiveSupport::Notifications event every time a FulfilApi::Error is raised. It gives an application a single place to report a failure of the Fulfil API to its APM — a counter of rate limit hits, an error tracker, a log line — without having to wrap every call into the gem in a begin/rescue.

Ruby routes every form of raise through Exception.exception (when raising a class) or Exception#exception (when raising an instance), which makes those two methods the hook for "an error is on its way up the stack". Building an error without raising it — HttpError.from_faraday_error, for example — publishes nothing.

Examples:

counting the errors of Fulfil in an APM

# config/initializers/fulfil_api.rb
FulfilApi.on_error do |error|
  Appsignal.increment_counter("fulfil_api_errors", 1, error: error.class.name)
end

subscribing through ActiveSupport directly, for the full payload

ActiveSupport::Notifications.subscribe(FulfilApi::Error::EVENT_NAME) do |event|
  Rails.logger.warn("Fulfil responded with #{event.payload[:status_code]}")
end

Constant Summary collapse

EVENT_NAME =

The name of the published event. It follows the <action>.<library> naming convention of Rails, so an APM that subscribes to a whole library through a /\.fulfil_api\z/ regexp picks it up along with everything the gem may instrument in the future.

"error.fulfil_api"
REENTRANCY_KEY =

The key of the fiber local flag guarding against infinite recursion. A subscriber that itself raises a FulfilApi::Error — one calling back into Fulfil, for instance — would otherwise publish an event from within the publication of an event, without end.

:fulfil_api_notifying_error

Instance Method Summary collapse

Instance Method Details

#exceptionFulfilApi::Error

Publishes EVENT_NAME for raise error and raise error, "message".

Returns:



58
59
60
# File 'lib/fulfil_api/error/notifiable.rb', line 58

def exception(*)
  super.tap(&:notify)
end

#notifyvoid

This method returns an undefined value.

Publishes EVENT_NAME for the receiver.



65
66
67
68
69
70
71
72
73
74
# File 'lib/fulfil_api/error/notifiable.rb', line 65

def notify
  return if Thread.current[REENTRANCY_KEY]

  Thread.current[REENTRANCY_KEY] = true
  ActiveSupport::Notifications.instrument(EVENT_NAME, notification_payload)
rescue StandardError => e
  warn "[FulfilApi] a subscriber of #{EVENT_NAME} raised #{e.class}: #{e.message}"
ensure
  Thread.current[REENTRANCY_KEY] = nil
end