Skip to content

Commit 83328c4

Browse files
committed
added application backtrace feature
1 parent 3a02a4d commit 83328c4

4 files changed

Lines changed: 38 additions & 5 deletions

File tree

lib/jsonapi/configuration.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class Configuration
2626
:top_level_meta_page_count_key,
2727
:allow_transactions,
2828
:include_backtraces_in_errors,
29+
:include_application_backtraces_in_errors,
2930
:exception_class_whitelist,
3031
:whitelist_all_exceptions,
3132
:always_include_to_one_linkage_data,
@@ -80,6 +81,10 @@ def initialize
8081
# responses. Defaults to `false` in production, and `true` otherwise.
8182
self.include_backtraces_in_errors = !Rails.env.production?
8283

84+
# Whether or not to include exception application backtraces in JSONAPI error
85+
# responses. Defaults to `false` in production, and `true` otherwise.
86+
self.include_application_backtraces_in_errors = !Rails.env.production?
87+
8388
# List of classes that should not be rescued by the operations processor.
8489
# For example, if you use Pundit for authorization, you might
8590
# raise a Pundit::NotAuthorizedError at some point during operations
@@ -246,6 +251,8 @@ def resource_finder=(resource_finder)
246251

247252
attr_writer :include_backtraces_in_errors
248253

254+
attr_writer :include_application_backtraces_in_errors
255+
249256
attr_writer :exception_class_whitelist
250257

251258
attr_writer :whitelist_all_exceptions

lib/jsonapi/exceptions.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ def errors
4949
meta[:backtrace] = exception.backtrace
5050
end
5151

52+
if JSONAPI.configuration.include_application_backtraces_in_errors
53+
meta ||= Hash.new
54+
meta[:exception] ||= exception.message
55+
meta[:application_backtrace] = exception.backtrace.select{|line| line =~ /#{Rails.root}/}
56+
end
57+
5258
[create_error_object(code: JSONAPI::INTERNAL_SERVER_ERROR,
5359
status: :internal_server_error,
5460
title: I18n.t('jsonapi-resources.exceptions.internal_server_error.title',

test/controllers/controller_test.rb

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,18 +126,37 @@ def test_exception_includes_backtrace_when_enabled
126126
JSONAPI.configuration.include_backtraces_in_errors = true
127127
assert_cacheable_get :index
128128
assert_response 500
129-
assert_includes @response.body, "backtrace", "expected backtrace in error body"
129+
assert_includes @response.body, '"backtrace"', "expected backtrace in error body"
130130

131131
JSONAPI.configuration.include_backtraces_in_errors = false
132132
assert_cacheable_get :index
133133
assert_response 500
134-
refute_includes @response.body, "backtrace", "expected backtrace in error body"
134+
refute_includes @response.body, '"backtrace"', "expected backtrace in error body"
135135

136136
ensure
137137
$PostProcessorRaisesErrors = false
138138
JSONAPI.configuration.include_backtraces_in_errors = original_config
139139
end
140140

141+
def test_exception_includes_application_backtrace_when_enabled
142+
original_config = JSONAPI.configuration.include_application_backtraces_in_errors
143+
$PostProcessorRaisesErrors = true
144+
145+
JSONAPI.configuration.include_application_backtraces_in_errors = true
146+
assert_cacheable_get :index
147+
assert_response 500
148+
assert_includes @response.body, '"application_backtrace"', "expected application backtrace in error body"
149+
150+
JSONAPI.configuration.include_application_backtraces_in_errors = false
151+
assert_cacheable_get :index
152+
assert_response 500
153+
refute_includes @response.body, '"application_backtrace"', "expected application backtrace in error body"
154+
155+
ensure
156+
$PostProcessorRaisesErrors = false
157+
JSONAPI.configuration.include_application_backtraces_in_errors = original_config
158+
end
159+
141160
def test_on_server_error_block_callback_with_exception
142161
original_config = JSONAPI.configuration.dup
143162
JSONAPI.configuration.exception_class_whitelist = []

test/test_helper.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ def assert_cacheable_get(action, *args)
513513
ActiveSupport::Notifications.subscribed(normal_query_callback, 'sql.active_record') do
514514
get action, *args
515515
end
516-
non_caching_response = json_response_sans_backtraces
516+
non_caching_response = json_response_sans_all_backtraces
517517
non_caching_status = response.status
518518

519519
# Don't let all the cache-testing requests mess with assert_query_count
@@ -565,7 +565,7 @@ def assert_cacheable_get(action, *args)
565565
)
566566
assert_equal(
567567
non_caching_response.pretty_inspect,
568-
json_response_sans_backtraces.pretty_inspect,
568+
json_response_sans_all_backtraces.pretty_inspect,
569569
"Cache (mode: #{mode}) #{phase} response body must match normal response"
570570
)
571571
assert_operator(
@@ -605,12 +605,13 @@ def assert_cacheable_get(action, *args)
605605

606606
private
607607

608-
def json_response_sans_backtraces
608+
def json_response_sans_all_backtraces
609609
return nil if response.body.to_s.strip.empty?
610610

611611
r = json_response.dup
612612
(r["errors"] || []).each do |err|
613613
err["meta"].delete("backtrace") if err.has_key?("meta")
614+
err["meta"].delete("application_backtrace") if err.has_key?("meta")
614615
end
615616
return r
616617
end

0 commit comments

Comments
 (0)