class Hayabusa
attr_reader :error_emails_pending
def initialize_errors
@error_emails_pending = {}
@error_emails_pending_mutex = Mutex.new
if @config[:error_emails_time]
@error_emails_time = @config[:error_emails_time]
elsif @config[:debug]
@error_emails_time = 5
else
@error_emails_time = 180
end
self.timeout(:time => @error_emails_time, &self.method(:flush_error_emails))
end
#Send error-emails based on error-emails-cache (cached so the same error isnt send out every time it occurrs to prevent spamming).
def flush_error_emails
@error_emails_pending_mutex.synchronize do
send_time_older_than = Time.new.to_i - @error_emails_time
@error_emails_pending.each do |backtrace_hash, error_email|
if send_time_older_than < error_email[:last_time].to_i and error_email[:messages].length < 1000
next
end
@config[:error_report_emails].each do |email|
next if !email or error_email[:messages].length <= 0
if error_email[:messages].length == 1
html = error_email[:messages].first
else
html = "First time: #{Datet.in(error_email[:first_time]).out}
"
html << "Last time: #{Datet.in(error_email[:last_time]).out}
"
html << "Number of errors: #{error_email[:messages].length}
"
count = 0
error_email[:messages].each do |error_msg|
count += 1
if count > 10
html << "
Limiting to showing 10 out of #{error_email[:messages].length} messages."
break
end
html << "
"
html << "Message #{count}
"
html << error_msg
end
end
self.mail(
:to => email,
:subject => error_email[:subject],
:html => html,
:from => @config[:error_report_from]
)
end
@error_emails_pending.delete(backtrace_hash)
end
end
end
#Handels a given error. Sends to the admin-emails.
def handle_error(e, args = {})
@error_emails_pending_mutex.synchronize do
if !Thread.current[:hayabusa] or !Thread.current[:hayabusa][:httpsession]
STDOUT.print "#{Knj::Errors.error_str(e)}\n\n"
end
browser = _httpsession.browser if _httpsession
send_email = true
send_email = false if !@config[:smtp_args]
send_email = false if !@config[:error_report_emails]
send_email = false if args.has_key?(:email) and !args[:email]
send_email = false if @config.key?(:error_report_bots) and !@config[:error_report_bots] and browser and browser["browser"] == "bot"
if send_email
backtrace_hash = Knj::ArrayExt.array_hash(e.backtrace)
if !@error_emails_pending.has_key?(backtrace_hash)
@error_emails_pending[backtrace_hash] = {
:first_time => Time.new,
:messages => [],
:subject => sprintf("Error @ %s", @config[:title]) + " (#{Knj::Strings.shorten(e.message, 100)})"
}
end
html = "An error occurred.
"
html << "#{Knj::Web.html(e.class.name)}: #{Knj::Web.html(e.message)}
"
e.backtrace.each do |line|
html << "#{Knj::Web.html(line)}
"
end
html << "
Post:
#{Php4r.print_r(_post, true)}" if _post html << "
#{Php4r.print_r(_get, true)}" if _get html << "
#{Php4r.print_r(_server, true).html}" if _server html << "
#{Php4r.print_r(_cookie, true).html}" if _meta html << "
#{Php4r.print_r(_session, true).html}" if _session html << "
#{Php4r.print_r(_session_hash, true).html}" if _session_hash error_hash = @error_emails_pending[backtrace_hash] error_hash[:last_time] = Time.new error_hash[:messages] << html end end end #Takes a proc and executes it. On error it alerts the error-message with javascript to the server, sends a javascript back and exits. def on_error_go_back(&block) begin block.call rescue => e self.alert(e.message).back end end #Prints a detailed overview of the object in the terminal from where the appserver was started. This can be used for debugging. def dprint(obj) STDOUT.print Php4r.print_r(obj, true) end #Prints a string with a single file-line-backtrace prepended which is useful for debugging. def debugs(str) #Get backtrace. backtrace_str = caller[0] backtrace_match = backtrace_str.match(/^(.+):(\d+):in /) STDOUT.print "#{File.basename(backtrace_match[1])}:#{backtrace_match[2]}: #{str}\n" end end