better error handling (#677)

* swap honeybadger for sentry

* better error pages
This commit is contained in:
Echo
2025-12-01 12:33:01 -05:00
committed by GitHub
parent 0260a16c6c
commit 64fc0f1f1b
18 changed files with 117 additions and 729 deletions

View File

@@ -53,5 +53,6 @@ module Harbor
config.middleware.use HtmlCompressor::Rack
config.middleware.use Rack::Attack
config.exceptions_app = routes
end
end

View File

@@ -1,36 +0,0 @@
---
# For more options, see https://docs.honeybadger.io/lib/ruby/gem-reference/configuration
api_key: 'hbp_IET1u9vKrC7IWjt45arAsfguTrGSFR1bSxEq'
# The environment your app is running in.
env: "<%= Rails.env %>"
# The absolute path to your project folder.
root: "<%= Rails.root.to_s %>"
# Honeybadger won't report errors in these environments.
development_environments:
- test
- development
- cucumber
- production # temporary disable
# By default, Honeybadger won't report errors in the development_environments.
# You can override this by explicitly setting report_data to true or false.
# report_data: true
# The current Git revision of your project. Defaults to the last commit hash.
# revision: null
# Enable verbose debug logging (useful for troubleshooting).
debug: false
# Ignore noisy errors
exceptions:
ignore:
- GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError
# disable insights lol
insights:
enabled: false

View File

@@ -2,4 +2,10 @@
# between 0 and 1.0 to sample on a portion of instances.
Autotuner.enabled = true
# The rest is handled by the honeybadger gem.
Autotuner.reporter = proc do |report|
Sentry.capture_message(
"Autotuner Suggestion",
level: :info,
extra: { report: report.to_s }
)
end

View File

@@ -1,55 +0,0 @@
# Honeybadger programmatic error filtering to prevent rate limit exhaustion
Honeybadger.configure do |config|
@error_counts = Hash.new { |hash, key| hash[key] = { hourly: [], daily: [] } }
# Rate limiting configuration
MAX_ERRORS_PER_HOUR = 10
MAX_ERRORS_PER_DAY = 50
config.before_notify do |notice|
if notice.error_class == "Norairrecord::Error" && notice.error_message&.include?("HTTP 429")
return false
end
error_index = generate_error_index notice
should_ignore = rate_limit_exceeded? error_index
record_error_occurrence error_index unless should_ignore
!should_ignore
end
private
def generate_error_index(notice)
if notice.backtrace&.any?
first_stack_line = notice.backtrace.first
"#{notice.error_class}:#{first_stack_line}"
else
controller = notice.context[:controller]
action = notice.context[:action]
"#{notice.error_class}:#{controller}:#{action}"
end
end
def rate_limit_exceeded?(error_index)
now = Time.current
one_hour_ago = now - 1.hour
one_day_ago = now - 1.day
@error_counts[error_index][:hourly].reject! { |timestamp| timestamp < one_hour_ago }
@error_counts[error_index][:daily].reject! { |timestamp| timestamp < one_day_ago }
hourly_count = @error_counts[error_index][:hourly].size
daily_count = @error_counts[error_index][:daily].size
hourly_count >= MAX_ERRORS_PER_HOUR || daily_count >= MAX_ERRORS_PER_DAY
end
def record_error_occurrence(error_index)
now = Time.current
@error_counts[error_index][:hourly] << now
@error_counts[error_index][:daily] << now
end
end

View File

@@ -205,4 +205,10 @@ Rails.application.routes.draw do
# SEO routes
get "/sitemap.xml", to: "sitemap#sitemap", defaults: { format: "xml" }
# fuck ups
match "/400", to: "errors#bad_request", via: :all
match "/404", to: "errors#not_found", via: :all
match "/422", to: "errors#unprocessable_entity", via: :all
match "/500", to: "errors#internal_server_error", via: :all
end