From b8fff51745c62166b40295b503e6c4bf2803dd37 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Fri, 16 Oct 2026 12:40:02 +0200 Subject: [PATCH] Read the documented SOLIDERRORS_* email environment variables The README documented SOLIDERRORS_SEND_EMAILS, _EMAIL_FROM, _EMAIL_TO and _EMAIL_SUBJECT_PREFIX, but nothing read them. Each email setting now falls back to its variable when not configured; configuration still wins. Co-Authored-By: Claude Opus 5.5 (1M context) --- README.md | 12 ++--- lib/solid_errors.rb | 22 ++++++++-- test/solid_errors/email_configuration_test.rb | 44 +++++++++++++++++++ 3 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 test/solid_errors/email_configuration_test.rb diff --git a/README.md b/README.md index a84cf03..8b88871 100644 --- a/README.md +++ b/README.md @@ -279,14 +279,14 @@ Solid Errors _can_ send email notifications whenever an error occurs, if your ap There are two ways to configure email notifications. First, you can use environment variables: -```ruby -ENV["SOLIDERRORS_SEND_EMAILS"] = true # defaults to false -ENV["SOLIDERRORS_EMAIL_FROM"] = "errors@myapp.com" # defaults to "solid_errors@noreply.com" -ENV["SOLIDERRORS_EMAIL_TO"] = "devs@myapp.com" # no default, must be set -ENV["SOLIDERRORS_EMAIL_SUBJECT_PREFIX"] = "[Application name][Environment]" # no default, optional +```sh +SOLIDERRORS_SEND_EMAILS=true # defaults to false +SOLIDERRORS_EMAIL_FROM=errors@myapp.com # defaults to solid_errors@noreply.com +SOLIDERRORS_EMAIL_TO=devs@myapp.com # no default, must be set +SOLIDERRORS_EMAIL_SUBJECT_PREFIX="[Application name][Environment]" # no default, optional ``` -Second, you can set the values via the configuration object: +Second, you can set the values via the configuration object, which takes precedence over the environment variables: ```ruby # Set authentication credentials and optional subject prefix for Solid Errors diff --git a/lib/solid_errors.rb b/lib/solid_errors.rb index 6997dce..36461ee 100644 --- a/lib/solid_errors.rb +++ b/lib/solid_errors.rb @@ -11,10 +11,7 @@ module SolidErrors mattr_accessor :base_controller_class, default: "::ActionController::Base" mattr_writer :username mattr_writer :password - mattr_accessor :send_emails, default: false - mattr_accessor :email_from, default: "solid_errors@noreply.com" - mattr_accessor :email_to - mattr_accessor :email_subject_prefix + mattr_writer :send_emails, :email_from, :email_to, :email_subject_prefix, default: nil mattr_accessor :email_every_occurrence, default: true mattr_accessor :destroy_after mattr_accessor :ignored_errors, default: [] @@ -33,6 +30,23 @@ def password @password ||= ENV["SOLIDERRORS_PASSWORD"] || @@password end + # Each email setting falls back to its SOLIDERRORS_* environment variable when not configured + def send_emails + @@send_emails.nil? ? ActiveModel::Type::Boolean.new.cast(ENV["SOLIDERRORS_SEND_EMAILS"]) || false : @@send_emails + end + + def email_from + @@email_from || ENV["SOLIDERRORS_EMAIL_FROM"] || "solid_errors@noreply.com" + end + + def email_to + @@email_to || ENV["SOLIDERRORS_EMAIL_TO"] + end + + def email_subject_prefix + @@email_subject_prefix || ENV["SOLIDERRORS_EMAIL_SUBJECT_PREFIX"] + end + # Whether the errors database has every table and column this version reads and writes. # Assert it in your test suite to catch a schema change you haven't applied yet. def migrated? diff --git a/test/solid_errors/email_configuration_test.rb b/test/solid_errors/email_configuration_test.rb new file mode 100644 index 0000000..53a7b19 --- /dev/null +++ b/test/solid_errors/email_configuration_test.rb @@ -0,0 +1,44 @@ +require "test_helper" + +class SolidErrors::EmailConfigurationTest < ActiveSupport::TestCase + SETTINGS = %i[send_emails email_from email_to email_subject_prefix] + ENV_VARS = %w[SOLIDERRORS_SEND_EMAILS SOLIDERRORS_EMAIL_FROM SOLIDERRORS_EMAIL_TO SOLIDERRORS_EMAIL_SUBJECT_PREFIX] + + setup do + @settings = SETTINGS.to_h { |name| [name, SolidErrors.class_variable_get(:"@@#{name}")] } + @env = ENV.to_h.slice(*ENV_VARS) + SETTINGS.each { |name| SolidErrors.public_send(:"#{name}=", nil) } + end + + teardown do + @settings.each { |name, value| SolidErrors.public_send(:"#{name}=", value) } + ENV_VARS.each { |var| ENV.delete(var) } + ENV.update(@env) + end + + test "email settings fall back to their environment variables" do + ENV.update( + "SOLIDERRORS_SEND_EMAILS" => "true", + "SOLIDERRORS_EMAIL_FROM" => "errors@example.com", + "SOLIDERRORS_EMAIL_TO" => "devs@example.com", + "SOLIDERRORS_EMAIL_SUBJECT_PREFIX" => "[App]" + ) + + assert_equal [true, "errors@example.com", "devs@example.com", "[App]"], + SETTINGS.map { |name| SolidErrors.public_send(name) } + assert SolidErrors.send_emails? + end + + test "configured email settings win over their environment variables" do + ENV.update("SOLIDERRORS_SEND_EMAILS" => "true", "SOLIDERRORS_EMAIL_FROM" => "env@example.com") + SolidErrors.send_emails = false + SolidErrors.email_from = "config@example.com" + + assert_equal [false, "config@example.com"], [SolidErrors.send_emails, SolidErrors.email_from] + end + + test "email settings keep their defaults when neither is set" do + assert_equal [false, "solid_errors@noreply.com", nil, nil], + SETTINGS.map { |name| SolidErrors.public_send(name) } + end +end