module Hoptoad
class Notice
# Parameters:
# :request (hash or ActionController::CgiRequest)
# :session (hash or CGI::Session)
# :environment (hash)
# :error_class (string)
# :error_message (string)
# :backtrace (array)
def initialize(params={})
@params = default_params.merge(params.delete_if { |k,v| v.nil? })
end
def default_params
{
:api_key => Hoptoad.api_key,
:request => {},
:session => {},
:environment => {},
:error_message => "Notification",
:backtrace => self.class.default_backtrace
}
end
def environment_data
environment_data = @params[:environment]
if @params[:request].respond_to?(:env)
environment_data.merge!(@params[:request].env.to_hash)
end
environment_data
end
def request_data
return @params[:request] if @params[:request].is_a?(Hash)
cgi_request = @params[:request]
{
:params => filtered_parameters(cgi_request.parameters.to_hash),
:rails_root => File.expand_path(RAILS_ROOT),
:url => "#{cgi_request.protocol}#{cgi_request.host}#{cgi_request.request_uri}"
}
end
def session_data
return @params[:session] if @params[:session].is_a?(Hash)
cgi_session = @params[:session]
{
:key => cgi_session.instance_variable_get("@session_id"),
:data => cgi_session.instance_variable_get("@data")
}
end
def to_hash
{
:api_key => @params[:api_key],
:error_class => @params[:error_class],
:error_message => @params[:error_message],
:backtrace => filtered_backtrace(@params[:backtrace]),
:environment => environment_data,
:request => request_data,
:session => session_data
}.delete_if { |key, value| value.nil? }
end
class << self
def build(hash_or_exception, request = {}, session = {}, environment = {})
error_message = "#{hash_or_exception.class.name}: #{hash_or_exception.message}"
new(
:error_class => hash_or_exception.class.name,
:error_message => error_message,
:backtrace => (hash_or_exception.backtrace || []),
:request => request,
:session => session,
:environment => environment
)
end
# TODO: yuck!
def default_backtrace
caller
end
end
private
def filtered_backtrace(backtrace)
if backtrace.to_a.size == 1
backtrace = backtrace.to_a.first.split(/\n\s*/)
end
backtrace.to_a.map do |line|
Hoptoad.backtrace_filters.inject(line) do |line, proc|
proc.call(line)
end
end
end
def filtered_parameters(parameters)
parameters.each do |k, v|
parameters[k] = "<filtered>" if Hoptoad.params_filters.any? do |filter|
k.to_s.match(/#{filter}/)
end
end
end
end
end