Skip to content

Commit

Permalink
Allow controllers to decorate Twirp::Error
Browse files Browse the repository at this point in the history
  • Loading branch information
julik committed Jan 23, 2024
1 parent 938789f commit 9ad66d1
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
14 changes: 10 additions & 4 deletions lib/rails_twirp/exception_handling.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ def process_action(*)
# 1. When we 'show exceptions' we make the exception bubble up—this is useful for testing
# If the exception gets raised here error reporting will happen in the middleware of the APM package
# higher in the call stack.
raise e unless http_request.show_exceptions?
#
# Note that between Rails 7.0 and 7.1 the show_exceptions? helper method on Request
# got removed, so we must make do with the config access instead.
raise e unless [true, :all].include?(http_request.get_header("action_dispatch.show_exceptions"))

# 2. We report the error to the error tracking service, this needs to be configured.
RailsTwirp.unhandled_exception_handler&.call(e)
Expand All @@ -33,11 +36,14 @@ def process_action(*)
# 3. When we want to show detailed exceptions we include the exception message in the error
if http_request.get_header("action_dispatch.show_detailed_exceptions")
self.response_body = Twirp::Error.internal_with(e)
return
else
# 4. Otherwise we just return a vague internal error message
self.response_body = Twirp::Error.internal("Internal error")
end

# 4. Otherwise we just return a vague internal error message
self.response_body = Twirp::Error.internal("Internal error")
decorate_twirp_error_response! if respond_to?(:decorate_twirp_error_response!)

self.response_body
end
end
end
19 changes: 19 additions & 0 deletions test/ping_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,25 @@ class PingControllerTest < RailsTwirp::IntegrationTest
Rails.application.env_config["action_dispatch.show_exceptions"] = false
end

test "decorates Twirp errors resulting from unhandled exceptions if the controller provides for it" do
Rails.application.env_config["action_dispatch.show_exceptions"] = true
Rails.application.env_config["action_dispatch.show_detailed_exceptions"] = false

PingsController.define_method(:decorate_twirp_error_response!)do
self.response_body.meta[:encrypted] = "abc"
end

req = RPC::DummyAPI::PingRequest.new
rpc RPC::DummyAPI::DummyService, "UncaughtError", req
assert_instance_of Twirp::Error, response
assert_equal :internal, response.code
assert_equal "Internal error", response.msg
assert_equal "abc", response.meta["encrypted"]
ensure
Rails.application.env_config["action_dispatch.show_detailed_exceptions"] = true
Rails.application.env_config["action_dispatch.show_exceptions"] = false
end

test "before error" do
req = RPC::DummyAPI::PingRequest.new
rpc RPC::DummyAPI::DummyService, "BeforeError", req
Expand Down

0 comments on commit 9ad66d1

Please sign in to comment.