square-hoptoad_notifier 2.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. data/CHANGELOG +427 -0
  2. data/INSTALL +25 -0
  3. data/MIT-LICENSE +22 -0
  4. data/README.md +435 -0
  5. data/README_FOR_HEROKU_ADDON.md +93 -0
  6. data/Rakefile +227 -0
  7. data/SUPPORTED_RAILS_VERSIONS +10 -0
  8. data/TESTING.rdoc +8 -0
  9. data/generators/hoptoad/hoptoad_generator.rb +88 -0
  10. data/generators/hoptoad/lib/insert_commands.rb +34 -0
  11. data/generators/hoptoad/lib/rake_commands.rb +24 -0
  12. data/generators/hoptoad/templates/capistrano_hook.rb +6 -0
  13. data/generators/hoptoad/templates/hoptoad_notifier_tasks.rake +25 -0
  14. data/generators/hoptoad/templates/initializer.rb +6 -0
  15. data/lib/hoptoad_notifier.rb +153 -0
  16. data/lib/hoptoad_notifier/backtrace.rb +99 -0
  17. data/lib/hoptoad_notifier/capistrano.rb +20 -0
  18. data/lib/hoptoad_notifier/configuration.rb +242 -0
  19. data/lib/hoptoad_notifier/notice.rb +337 -0
  20. data/lib/hoptoad_notifier/rack.rb +42 -0
  21. data/lib/hoptoad_notifier/rails.rb +41 -0
  22. data/lib/hoptoad_notifier/rails/action_controller_catcher.rb +30 -0
  23. data/lib/hoptoad_notifier/rails/controller_methods.rb +68 -0
  24. data/lib/hoptoad_notifier/rails/error_lookup.rb +33 -0
  25. data/lib/hoptoad_notifier/rails/javascript_notifier.rb +42 -0
  26. data/lib/hoptoad_notifier/rails3_tasks.rb +82 -0
  27. data/lib/hoptoad_notifier/railtie.rb +32 -0
  28. data/lib/hoptoad_notifier/sender.rb +83 -0
  29. data/lib/hoptoad_notifier/shared_tasks.rb +29 -0
  30. data/lib/hoptoad_notifier/tasks.rb +83 -0
  31. data/lib/hoptoad_notifier/user_informer.rb +23 -0
  32. data/lib/hoptoad_notifier/version.rb +3 -0
  33. data/lib/hoptoad_tasks.rb +44 -0
  34. data/lib/rails/generators/hoptoad/hoptoad_generator.rb +94 -0
  35. data/lib/templates/javascript_notifier.erb +13 -0
  36. data/lib/templates/rescue.erb +91 -0
  37. data/rails/init.rb +1 -0
  38. data/script/integration_test.rb +38 -0
  39. data/test/backtrace_test.rb +118 -0
  40. data/test/catcher_test.rb +331 -0
  41. data/test/configuration_test.rb +216 -0
  42. data/test/helper.rb +248 -0
  43. data/test/hoptoad_tasks_test.rb +152 -0
  44. data/test/javascript_notifier_test.rb +52 -0
  45. data/test/logger_test.rb +85 -0
  46. data/test/notice_test.rb +448 -0
  47. data/test/notifier_test.rb +222 -0
  48. data/test/rack_test.rb +58 -0
  49. data/test/rails_initializer_test.rb +36 -0
  50. data/test/sender_test.rb +161 -0
  51. data/test/user_informer_test.rb +29 -0
  52. metadata +225 -0
@@ -0,0 +1,24 @@
1
+ Rails::Generator::Commands::Create.class_eval do
2
+ def rake(cmd, opts = {})
3
+ logger.rake "rake #{cmd}"
4
+ unless system("rake #{cmd}")
5
+ logger.rake "#{cmd} failed. Rolling back"
6
+ command(:destroy).invoke!
7
+ end
8
+ end
9
+ end
10
+
11
+ Rails::Generator::Commands::Destroy.class_eval do
12
+ def rake(cmd, opts = {})
13
+ unless opts[:generate_only]
14
+ logger.rake "rake #{cmd}"
15
+ system "rake #{cmd}"
16
+ end
17
+ end
18
+ end
19
+
20
+ Rails::Generator::Commands::List.class_eval do
21
+ def rake(cmd, opts = {})
22
+ logger.rake "rake #{cmd}"
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+
2
+ Dir[File.join(File.dirname(__FILE__), '..', 'vendor', 'gems', 'hoptoad_notifier-*')].each do |vendored_notifier|
3
+ $: << File.join(vendored_notifier, 'lib')
4
+ end
5
+
6
+ require 'hoptoad_notifier/capistrano'
@@ -0,0 +1,25 @@
1
+ # Don't load anything when running the gems:* tasks.
2
+ # Otherwise, hoptoad_notifier will be considered a framework gem.
3
+ # https://thoughtbot.lighthouseapp.com/projects/14221/tickets/629
4
+ unless ARGV.any? {|a| a =~ /^gems/}
5
+
6
+ Dir[File.join(RAILS_ROOT, 'vendor', 'gems', 'hoptoad_notifier-*')].each do |vendored_notifier|
7
+ $: << File.join(vendored_notifier, 'lib')
8
+ end
9
+
10
+ begin
11
+ require 'hoptoad_notifier/tasks'
12
+ rescue LoadError => exception
13
+ namespace :hoptoad do
14
+ %w(deploy test log_stdout).each do |task_name|
15
+ desc "Missing dependency for hoptoad:#{task_name}"
16
+ task task_name do
17
+ $stderr.puts "Failed to run hoptoad:#{task_name} because of missing dependency."
18
+ $stderr.puts "You probably need to run `rake gems:install` to install the hoptoad_notifier gem"
19
+ abort exception.inspect
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,6 @@
1
+ <% if Rails::VERSION::MAJOR < 3 && Rails::VERSION::MINOR < 2 -%>
2
+ require 'hoptoad_notifier/rails'
3
+ <% end -%>
4
+ HoptoadNotifier.configure do |config|
5
+ config.api_key = <%= api_key_expression %>
6
+ end
@@ -0,0 +1,153 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'rubygems'
4
+ begin
5
+ require 'active_support'
6
+ rescue LoadError
7
+ require 'activesupport'
8
+ end
9
+ require 'hoptoad_notifier/version'
10
+ require 'hoptoad_notifier/configuration'
11
+ require 'hoptoad_notifier/notice'
12
+ require 'hoptoad_notifier/sender'
13
+ require 'hoptoad_notifier/backtrace'
14
+ require 'hoptoad_notifier/rack'
15
+ require 'hoptoad_notifier/user_informer'
16
+
17
+ require 'hoptoad_notifier/railtie' if defined?(Rails::Railtie)
18
+
19
+ # Gem for applications to automatically post errors to the Hoptoad of their choice.
20
+ module HoptoadNotifier
21
+
22
+ API_VERSION = "2.0"
23
+ LOG_PREFIX = "** [Hoptoad] "
24
+
25
+ HEADERS = {
26
+ 'Content-type' => 'text/xml',
27
+ 'Accept' => 'text/xml, application/xml'
28
+ }
29
+
30
+ class << self
31
+ # The sender object is responsible for delivering formatted data to the Hoptoad server.
32
+ # Must respond to #send_to_hoptoad. See HoptoadNotifier::Sender.
33
+ attr_accessor :sender
34
+
35
+ # A Hoptoad configuration object. Must act like a hash and return sensible
36
+ # values for all Hoptoad configuration options. See HoptoadNotifier::Configuration.
37
+ attr_accessor :configuration
38
+
39
+ # Tell the log that the Notifier is good to go
40
+ def report_ready
41
+ write_verbose_log("Notifier #{VERSION} ready to catch errors")
42
+ end
43
+
44
+ # Prints out the environment info to the log for debugging help
45
+ def report_environment_info
46
+ write_verbose_log("Environment Info: #{environment_info}")
47
+ end
48
+
49
+ # Prints out the response body from Hoptoad for debugging help
50
+ def report_response_body(response)
51
+ write_verbose_log("Response from Hoptoad: \n#{response}")
52
+ end
53
+
54
+ # Returns the Ruby version, Rails version, and current Rails environment
55
+ def environment_info
56
+ info = "[Ruby: #{RUBY_VERSION}]"
57
+ info << " [#{configuration.framework}]"
58
+ info << " [Env: #{configuration.environment_name}]"
59
+ end
60
+
61
+ # Writes out the given message to the #logger
62
+ def write_verbose_log(message)
63
+ logger.info LOG_PREFIX + message if logger
64
+ end
65
+
66
+ # Look for the Rails logger currently defined
67
+ def logger
68
+ self.configuration.logger
69
+ end
70
+
71
+ # Call this method to modify defaults in your initializers.
72
+ #
73
+ # @example
74
+ # HoptoadNotifier.configure do |config|
75
+ # config.api_key = '1234567890abcdef'
76
+ # config.secure = false
77
+ # end
78
+ def configure(silent = false)
79
+ self.configuration ||= Configuration.new
80
+ yield(configuration)
81
+ self.sender = Sender.new(configuration)
82
+ report_ready unless silent
83
+ end
84
+
85
+ # Sends an exception manually using this method, even when you are not in a controller.
86
+ #
87
+ # @param [Exception] exception The exception you want to notify Hoptoad about.
88
+ # @param [Hash] opts Data that will be sent to Hoptoad.
89
+ #
90
+ # @option opts [String] :api_key The API key for this project. The API key is a unique identifier that Hoptoad uses for identification.
91
+ # @option opts [String] :error_message The error returned by the exception (or the message you want to log).
92
+ # @option opts [String] :backtrace A backtrace, usually obtained with +caller+.
93
+ # @option opts [String] :request The controller's request object.
94
+ # @option opts [String] :session The contents of the user's session.
95
+ # @option opts [String] :environment ENV merged with the contents of the request's environment.
96
+ def notify(exception, opts = {})
97
+ send_notice(build_notice_for(exception, opts))
98
+ end
99
+
100
+ # Sends the notice unless it is one of the default ignored exceptions
101
+ # @see HoptoadNotifier.notify
102
+ def notify_or_ignore(exception, opts = {})
103
+ notice = build_notice_for(exception, opts)
104
+ send_notice(notice) unless notice.ignore?
105
+ end
106
+
107
+ def build_lookup_hash_for(exception, options = {})
108
+ notice = build_notice_for(exception, options)
109
+
110
+ result = {}
111
+ result[:action] = notice.action rescue nil
112
+ result[:component] = notice.component rescue nil
113
+ result[:error_class] = notice.error_class if notice.error_class
114
+ result[:environment_name] = 'production'
115
+
116
+ unless notice.backtrace.lines.empty?
117
+ result[:file] = notice.backtrace.lines.first.file
118
+ result[:line_number] = notice.backtrace.lines.first.number
119
+ end
120
+
121
+ result
122
+ end
123
+
124
+ private
125
+
126
+ def send_notice(notice)
127
+ if configuration.public?
128
+ sender.send_to_hoptoad(notice.to_xml)
129
+ end
130
+ end
131
+
132
+ def build_notice_for(exception, opts = {})
133
+ exception = unwrap_exception(exception)
134
+ if exception.respond_to?(:to_hash)
135
+ opts = opts.merge(exception.to_hash)
136
+ else
137
+ opts = opts.merge(:exception => exception)
138
+ end
139
+ Notice.new(configuration.merge(opts))
140
+ end
141
+
142
+ def unwrap_exception(exception)
143
+ if exception.respond_to?(:original_exception)
144
+ exception.original_exception
145
+ elsif exception.respond_to?(:continued_exception)
146
+ exception.continued_exception
147
+ else
148
+ exception
149
+ end
150
+ end
151
+ end
152
+ end
153
+
@@ -0,0 +1,99 @@
1
+ module HoptoadNotifier
2
+ # Front end to parsing the backtrace for each notice
3
+ class Backtrace
4
+
5
+ # Handles backtrace parsing line by line
6
+ class Line
7
+
8
+ INPUT_FORMAT = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}.freeze
9
+
10
+ # The file portion of the line (such as app/models/user.rb)
11
+ attr_reader :file
12
+
13
+ # The line number portion of the line
14
+ attr_reader :number
15
+
16
+ # The method of the line (such as index)
17
+ attr_reader :method
18
+
19
+ # Parses a single line of a given backtrace
20
+ # @param [String] unparsed_line The raw line from +caller+ or some backtrace
21
+ # @return [Line] The parsed backtrace line
22
+ def self.parse(unparsed_line)
23
+ _, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a
24
+ new(file, number, method)
25
+ end
26
+
27
+ def initialize(file, number, method)
28
+ self.file = file
29
+ self.number = number
30
+ self.method = method
31
+ end
32
+
33
+ # Reconstructs the line in a readable fashion
34
+ def to_s
35
+ "#{file}:#{number}:in `#{method}'"
36
+ end
37
+
38
+ def ==(other)
39
+ to_s == other.to_s
40
+ end
41
+
42
+ def inspect
43
+ "<Line:#{to_s}>"
44
+ end
45
+
46
+ private
47
+
48
+ attr_writer :file, :number, :method
49
+ end
50
+
51
+ # holder for an Array of Backtrace::Line instances
52
+ attr_reader :lines
53
+
54
+ def self.parse(ruby_backtrace, opts = {})
55
+ ruby_lines = split_multiline_backtrace(ruby_backtrace)
56
+
57
+ filters = opts[:filters] || []
58
+ filtered_lines = ruby_lines.to_a.map do |line|
59
+ filters.inject(line) do |line, proc|
60
+ proc.call(line)
61
+ end
62
+ end.compact
63
+
64
+ lines = filtered_lines.collect do |unparsed_line|
65
+ Line.parse(unparsed_line)
66
+ end
67
+
68
+ instance = new(lines)
69
+ end
70
+
71
+ def initialize(lines)
72
+ self.lines = lines
73
+ end
74
+
75
+ def inspect
76
+ "<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">"
77
+ end
78
+
79
+ def ==(other)
80
+ if other.respond_to?(:lines)
81
+ lines == other.lines
82
+ else
83
+ false
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ attr_writer :lines
90
+
91
+ def self.split_multiline_backtrace(backtrace)
92
+ if backtrace.to_a.size == 1
93
+ backtrace.to_a.first.split(/\n\s*/)
94
+ else
95
+ backtrace
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,20 @@
1
+ # Defines deploy:notify_hoptoad which will send information about the deploy to Hoptoad.
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+ after "deploy", "deploy:notify_hoptoad"
5
+ after "deploy:migrations", "deploy:notify_hoptoad"
6
+
7
+ namespace :deploy do
8
+ desc "Notify Hoptoad of the deployment"
9
+ task :notify_hoptoad, :except => { :no_release => true } do
10
+ rails_env = fetch(:hoptoad_env, fetch(:rails_env, "production"))
11
+ local_user = ENV['USER'] || ENV['USERNAME']
12
+ executable = RUBY_PLATFORM.downcase.include?('mswin') ? 'rake.bat' : 'rake'
13
+ notify_command = "#{executable} hoptoad:deploy TO=#{rails_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
14
+ notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
15
+ puts "Notifying Hoptoad of Deploy (#{notify_command})"
16
+ `#{notify_command}`
17
+ puts "Hoptoad Notification Complete."
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,242 @@
1
+ module HoptoadNotifier
2
+ # Used to set up and modify settings for the notifier.
3
+ class Configuration
4
+
5
+ OPTIONS = [:api_key, :backtrace_filters, :development_environments,
6
+ :development_lookup, :environment_name, :host,
7
+ :http_open_timeout, :http_read_timeout, :ignore, :ignore_by_filters,
8
+ :ignore_user_agent, :notifier_name, :notifier_url, :notifier_version,
9
+ :params_filters, :project_root, :port, :protocol, :proxy_host,
10
+ :proxy_pass, :proxy_port, :proxy_user, :secure, :framework,
11
+ :user_information].freeze
12
+
13
+ # The API key for your project, found on the project edit form.
14
+ attr_accessor :api_key
15
+
16
+ # The host to connect to (defaults to hoptoadapp.com).
17
+ attr_accessor :host
18
+
19
+ # The port on which your Hoptoad server runs (defaults to 443 for secure
20
+ # connections, 80 for insecure connections).
21
+ attr_accessor :port
22
+
23
+ # +true+ for https connections, +false+ for http connections.
24
+ attr_accessor :secure
25
+
26
+ # The HTTP open timeout in seconds (defaults to 2).
27
+ attr_accessor :http_open_timeout
28
+
29
+ # The HTTP read timeout in seconds (defaults to 5).
30
+ attr_accessor :http_read_timeout
31
+
32
+ # The hostname of your proxy server (if using a proxy)
33
+ attr_accessor :proxy_host
34
+
35
+ # The port of your proxy server (if using a proxy)
36
+ attr_accessor :proxy_port
37
+
38
+ # The username to use when logging into your proxy server (if using a proxy)
39
+ attr_accessor :proxy_user
40
+
41
+ # The password to use when logging into your proxy server (if using a proxy)
42
+ attr_accessor :proxy_pass
43
+
44
+ # A list of parameters that should be filtered out of what is sent to Hoptoad.
45
+ # By default, all "password" attributes will have their contents replaced.
46
+ attr_reader :params_filters
47
+
48
+ # A list of filters for cleaning and pruning the backtrace. See #filter_backtrace.
49
+ attr_reader :backtrace_filters
50
+
51
+ # A list of filters for ignoring exceptions. See #ignore_by_filter.
52
+ attr_reader :ignore_by_filters
53
+
54
+ # A list of exception classes to ignore. The array can be appended to.
55
+ attr_reader :ignore
56
+
57
+ # A list of user agents that are being ignored. The array can be appended to.
58
+ attr_reader :ignore_user_agent
59
+
60
+ # A list of environments in which notifications should not be sent.
61
+ attr_accessor :development_environments
62
+
63
+ # +true+ if you want to check for production errors matching development errors, +false+ otherwise.
64
+ attr_accessor :development_lookup
65
+
66
+ # The name of the environment the application is running in
67
+ attr_accessor :environment_name
68
+
69
+ # The path to the project in which the error occurred, such as the RAILS_ROOT
70
+ attr_accessor :project_root
71
+
72
+ # The name of the notifier library being used to send notifications (such as "Hoptoad Notifier")
73
+ attr_accessor :notifier_name
74
+
75
+ # The version of the notifier library being used to send notifications (such as "1.0.2")
76
+ attr_accessor :notifier_version
77
+
78
+ # The url of the notifier library being used to send notifications
79
+ attr_accessor :notifier_url
80
+
81
+ # The logger used by HoptoadNotifier
82
+ attr_accessor :logger
83
+
84
+ # The text that the placeholder is replaced with. {{error_id}} is the actual error number.
85
+ attr_accessor :user_information
86
+
87
+ # The framework HoptoadNotifier is configured to use
88
+ attr_accessor :framework
89
+
90
+ DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
91
+
92
+ DEFAULT_BACKTRACE_FILTERS = [
93
+ lambda { |line|
94
+ if defined?(HoptoadNotifier.configuration.project_root) && HoptoadNotifier.configuration.project_root.to_s != ''
95
+ line.gsub(/#{HoptoadNotifier.configuration.project_root}/, "[PROJECT_ROOT]")
96
+ else
97
+ line
98
+ end
99
+ },
100
+ lambda { |line| line.gsub(/^\.\//, "") },
101
+ lambda { |line|
102
+ if defined?(Gem)
103
+ Gem.path.inject(line) do |line, path|
104
+ line.gsub(/#{path}/, "[GEM_ROOT]")
105
+ end
106
+ end
107
+ },
108
+ lambda { |line| line if line !~ %r{lib/hoptoad_notifier} }
109
+ ].freeze
110
+
111
+ IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound',
112
+ 'ActionController::RoutingError',
113
+ 'ActionController::InvalidAuthenticityToken',
114
+ 'CGI::Session::CookieStore::TamperedWithCookie',
115
+ 'ActionController::UnknownAction',
116
+ 'AbstractController::ActionNotFound']
117
+
118
+ alias_method :secure?, :secure
119
+
120
+ def initialize
121
+ @secure = false
122
+ @host = 'hoptoadapp.com'
123
+ @http_open_timeout = 2
124
+ @http_read_timeout = 5
125
+ @params_filters = DEFAULT_PARAMS_FILTERS.dup
126
+ @backtrace_filters = DEFAULT_BACKTRACE_FILTERS.dup
127
+ @ignore_by_filters = []
128
+ @ignore = IGNORE_DEFAULT.dup
129
+ @ignore_user_agent = []
130
+ @development_environments = %w(development test cucumber)
131
+ @development_lookup = true
132
+ @notifier_name = 'Hoptoad Notifier'
133
+ @notifier_version = VERSION
134
+ @notifier_url = 'http://hoptoadapp.com'
135
+ @framework = 'Standalone'
136
+ @user_information = 'Hoptoad Error {{error_id}}'
137
+ end
138
+
139
+ # Takes a block and adds it to the list of backtrace filters. When the filters
140
+ # run, the block will be handed each line of the backtrace and can modify
141
+ # it as necessary.
142
+ #
143
+ # @example
144
+ # config.filter_bracktrace do |line|
145
+ # line.gsub(/^#{Rails.root}/, "[RAILS_ROOT]")
146
+ # end
147
+ #
148
+ # @param [Proc] block The new backtrace filter.
149
+ # @yieldparam [String] line A line in the backtrace.
150
+ def filter_backtrace(&block)
151
+ self.backtrace_filters << block
152
+ end
153
+
154
+ # Takes a block and adds it to the list of ignore filters.
155
+ # When the filters run, the block will be handed the exception.
156
+ # @example
157
+ # config.ignore_by_filter do |exception_data|
158
+ # true if exception_data[:error_class] == "RuntimeError"
159
+ # end
160
+ #
161
+ # @param [Proc] block The new ignore filter
162
+ # @yieldparam [Hash] data The exception data given to +HoptoadNotifier.notify+
163
+ # @yieldreturn [Boolean] If the block returns true the exception will be ignored, otherwise it will be processed by hoptoad.
164
+ def ignore_by_filter(&block)
165
+ self.ignore_by_filters << block
166
+ end
167
+
168
+ # Overrides the list of default ignored errors.
169
+ #
170
+ # @param [Array<Exception>] names A list of exceptions to ignore.
171
+ def ignore_only=(names)
172
+ @ignore = [names].flatten
173
+ end
174
+
175
+ # Overrides the list of default ignored user agents
176
+ #
177
+ # @param [Array<String>] A list of user agents to ignore
178
+ def ignore_user_agent_only=(names)
179
+ @ignore_user_agent = [names].flatten
180
+ end
181
+
182
+ # Allows config options to be read like a hash
183
+ #
184
+ # @param [Symbol] option Key for a given attribute
185
+ def [](option)
186
+ send(option)
187
+ end
188
+
189
+ # Returns a hash of all configurable options
190
+ def to_hash
191
+ OPTIONS.inject({}) do |hash, option|
192
+ hash.merge(option.to_sym => send(option))
193
+ end
194
+ end
195
+
196
+ # Returns a hash of all configurable options merged with +hash+
197
+ #
198
+ # @param [Hash] hash A set of configuration options that will take precedence over the defaults
199
+ def merge(hash)
200
+ to_hash.merge(hash)
201
+ end
202
+
203
+ # Determines if the notifier will send notices.
204
+ # @return [Boolean] Returns +false+ if in a development environment, +true+ otherwise.
205
+ def public?
206
+ !development_environments.include?(environment_name)
207
+ end
208
+
209
+ def port
210
+ @port || default_port
211
+ end
212
+
213
+ def protocol
214
+ if secure?
215
+ 'https'
216
+ else
217
+ 'http'
218
+ end
219
+ end
220
+
221
+ def js_notifier=(*args)
222
+ warn '[HOPTOAD] config.js_notifier has been deprecated and has no effect. You should use <%= hoptoad_javascript_notifier %> directly at the top of your layouts. Be sure to place it before all other javascript.'
223
+ end
224
+
225
+ def environment_filters
226
+ warn 'config.environment_filters has been deprecated and has no effect.'
227
+ []
228
+ end
229
+
230
+ private
231
+
232
+ def default_port
233
+ if secure?
234
+ 443
235
+ else
236
+ 80
237
+ end
238
+ end
239
+
240
+ end
241
+
242
+ end