diff --git a/CHANGELOG.md b/CHANGELOG.md index a2fdb47..c96f7b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,18 @@ Changelog for the gruf gem. This includes internal history before the gem was ma ### Pending release * [#190] Remove unsued `e2mmap` and `thwait` gems from `runtime_dependency`. +* [#184] [Breaking] Controller unhandled errors should be passed as BadStatus to interceptors. + * Server interceptors should now expect a `GRPC::BadStatus` error in the case of unhandled errors. + Orignal unhandled error can be reached via `cause`. example: + ```ruby + def call + begin + yield + rescue => err + err.cause + end + end + ``` ### 2.19.0 diff --git a/lib/gruf/controllers/base.rb b/lib/gruf/controllers/base.rb index e86fdf0..43a5019 100644 --- a/lib/gruf/controllers/base.rb +++ b/lib/gruf/controllers/base.rb @@ -92,13 +92,13 @@ def process_action(method_key, &block) def call(method_key, &block) Interceptors::Context.new(@interceptors).intercept! do process_action(method_key, &block) + rescue GRPC::BadStatus + raise # passthrough, to be caught by Gruf::Interceptors::Timer + rescue GRPC::Core::CallError, StandardError => e # CallError is not a StandardError + set_debug_info(e.message, e.backtrace) if Gruf.backtrace_on_error + error_message = Gruf.use_exception_message ? e.message : Gruf.internal_error_message + fail!(:internal, :unknown, error_message) end - rescue GRPC::BadStatus - raise # passthrough, to be caught by Gruf::Interceptors::Timer - rescue GRPC::Core::CallError, StandardError => e # CallError is not a StandardError - set_debug_info(e.message, e.backtrace) if Gruf.backtrace_on_error - error_message = Gruf.use_exception_message ? e.message : Gruf.internal_error_message - fail!(:internal, :unknown, error_message) end end end diff --git a/spec/gruf/controllers/base_spec.rb b/spec/gruf/controllers/base_spec.rb index 0b1c631..3a16b89 100644 --- a/spec/gruf/controllers/base_spec.rb +++ b/spec/gruf/controllers/base_spec.rb @@ -97,6 +97,16 @@ end end + it 'raises a GRPC::Internal error to interceptors' do + Gruf.interceptors.use(TestServerInterceptor) + expect_any_instance_of(TestServerInterceptor).to receive(:call) do |&block| + error = nil + expect { block.call }.to raise_error(GRPC::Internal) { |err| error = err } + raise error if error + end + expect { subject }.to raise_error(GRPC::Internal) + end + context 'when backtrace_on_error is set to true' do before do Gruf.backtrace_on_error = true