diff --git a/lib/log_overrider.rb b/lib/log_overrider.rb index 47df57b97..6ef3dcf72 100644 --- a/lib/log_overrider.rb +++ b/lib/log_overrider.rb @@ -11,6 +11,23 @@ class ActionView::LogSubscriber alias :render_collection :render_template end +module ActionDispatch + class ShowExceptions + private + def log_error(exception) + return unless logger + + ActiveSupport::Deprecation.silence do + message = "event=error error_class=#{exception.class} error_message='#{exception.message}' " + message << "orig_error_message='#{exception.original_exception.message}'" if exception.respond_to?(:original_exception) + message << "annotated_source='#{exception.annoted_source_code.to_s}' " if exception.respond_to?(:annoted_source_code) + message << "app_backtrace='#{application_trace(exception).join(";")}'" + logger.fatal("\n\n#{message}\n\n") + end + end + end +end + class ActionController::LogSubscriber def start_processing(event) #noop diff --git a/spec/controllers/aspects_controller_spec.rb b/spec/controllers/aspects_controller_spec.rb index 57ec10329..11fe163a3 100644 --- a/spec/controllers/aspects_controller_spec.rb +++ b/spec/controllers/aspects_controller_spec.rb @@ -31,6 +31,19 @@ describe AspectsController do it_should_behave_like "it overrides the logs on success" end + describe "custom logging on error" do + class FakeError < RuntimeError; attr_accessor :original_exception; end + before do + @action = :index + @desired_error_message = "I love errors" + @error = FakeError.new(@desired_error_message) + @orig_error_message = "I loooooove nested errors!" + @error.original_exception = NoMethodError.new(@orig_error_message) + @controller.stub(:index).and_raise(@error) + end + it_should_behave_like "it overrides the logs on error" + end + describe "custom logging on redirect" do before do @action = :show diff --git a/spec/shared_behaviors/log_override.rb b/spec/shared_behaviors/log_override.rb index 8a604ec08..f91538215 100644 --- a/spec/shared_behaviors/log_override.rb +++ b/spec/shared_behaviors/log_override.rb @@ -1,12 +1,18 @@ class FakeLogger attr_accessor :infos + attr_accessor :lines def initialize self.infos = [] + self.lines = [] end def info line self.infos << line + self.lines << line + end + def fatal line + self.lines << line end end @@ -51,6 +57,27 @@ shared_examples_for 'it overrides the logs on success' do end end +shared_examples_for 'it overrides the logs on error' do + before do + Rails.stub(:logger).and_return(FakeLogger.new) + begin + get @action, @action_params + rescue Exception => e + ActionDispatch::ShowExceptions.new(nil).send(:log_error,e) + end + @line = Rails.logger.lines.last + end + it 'logs the backtrace' do + @line.should =~ /app_backtrace=/ + end + it 'logs the error message' do + @line.should =~ /error_message='#{@desired_error_message}'/ + end + it 'logs the original error message, if it exists' do + @line.should =~ /orig_error_message='#{@orig_error_message}'/ if @orig_error_message + end +end + shared_examples_for 'it overrides the logs on redirect' do before do Rails.stub(:logger).and_return(FakeLogger.new)