Skip to content

Instantly share code, notes, and snippets.

@tombruijn
Last active December 14, 2017 10:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tombruijn/87dcf4e714f9158457d10277e6cf3ce4 to your computer and use it in GitHub Desktop.
Save tombruijn/87dcf4e714f9158457d10277e6cf3ce4 to your computer and use it in GitHub Desktop.
# Custom method to track exceptions regardless if an AppSignal transaction is
# currently active.
#
# When an AppSignal transaction is already active for this thread, it will add
# the exception to the currently active transaction. Note that only one
# exception can be added a transaction.
#
# When no AppSignal transactions are active for this thread it will create one
# temporarily, add the exception to the temporary transaction and send it to
# AppSignal.
#
# This method's behavior is similar to `Appsignal.send_exception`, but is more
# flexible and checks if a transaction is already running before creating a new
# transaction.
#
# @example Standalone example (no transaction active)
# # This exception will be tracked on a new transaction, as none are active
# # for this thread.
# custom_add_exception(
# RuntimeError.new("foo"),
# :namespace => "optional_namespace_name",
# :action => "optional_action_name"
# )
#
# @example Standalone example in rescue block
# begin
# raise "foo"
# rescue => error
# # This exception will be tracked on a new transaction, as none are active
# # for this thread.
# custom_add_exception(
# error,
# :namespace => "optional_namespace_name",
# :action => "optional_action_name"
# )
# end
#
# @example Example with transaction already active
# # Appsignal.monitor_transaction starts a transaction
# Appsignal.monitor_transaction "process_action.foo" do
# # This exception will added to the already active transaction
# custom_add_exception RuntimeError.new("bar")
# end
#
# @param exception [Exception] The exception to record.
# @param options [Hash<Symbol, Object>] Options for the new transaction, if no
# transaction is currently active.
# @option options [String] :namespace The namespace to record the exception on.
# when no transaction is currently active. Default: "background".
# @option options [String] :action The action to use for the new transaction,
# when no transaction is currently active.
# @return [void]
def custom_add_exception(exception, options = {})
return unless Appsignal.active?
return unless exception.is_a?(Exception)
# See if a transaction is currently active, e.g. in a Rails action
transaction = Appsignal::Transaction.current
transaction_active = !transaction.nil_transaction?
# If no transaction is active, create a new one specifically to send the
# given error.
unless transaction_active
transaction = Appsignal::Transaction.new(
SecureRandom.uuid,
options.fetch(:namespace, Appsignal::Transaction::BACKGROUND_JOB),
Appsignal::Transaction::GenericRequest.new({})
)
transaction.set_action_if_nil(options[:action]) if options[:action]
end
transaction.add_exception(exception)
# Complete the special transaction to send it to AppSignal.
# This creates the same behavior as `Appsignal.send_exception` when no
# transaction is currently active.
transaction.complete unless transaction_active
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment