diff --git a/enterprise/app/services/whatsapp/call_service.rb b/enterprise/app/services/whatsapp/call_service.rb index 2683332a0..ec8205e63 100644 --- a/enterprise/app/services/whatsapp/call_service.rb +++ b/enterprise/app/services/whatsapp/call_service.rb @@ -51,9 +51,8 @@ class Whatsapp::CallService end def forward_answer_to_meta! - svc = call.inbox.channel.provider_service - raise Voice::CallErrors::CallFailed, 'Meta pre_accept failed' unless svc.pre_accept_call(call.provider_call_id, sdp_answer) - raise Voice::CallErrors::CallFailed, 'Meta accept failed' unless svc.accept_call(call.provider_call_id, sdp_answer) + invoke_provider!(:pre_accept_call, sdp_answer) + invoke_provider!(:accept_call, sdp_answer) end # Take ownership of the conversation if no one holds it; leave assignee alone otherwise (transfer via UI). @@ -64,8 +63,8 @@ class Whatsapp::CallService # Raise on Meta failure (bool false or transport error) so callers bail before # finalizing local state — otherwise we'd mark a still-active call as ended # and broadcast voice_call.ended while Meta thinks it's live. - def invoke_provider!(method) - success = call.inbox.channel.provider_service.public_send(method, call.provider_call_id) + def invoke_provider!(method, *) + success = call.inbox.channel.provider_service.public_send(method, call.provider_call_id, *) raise Voice::CallErrors::CallFailed, "Meta #{method} failed" unless success rescue Voice::CallErrors::CallFailed raise diff --git a/spec/enterprise/services/whatsapp/call_service_spec.rb b/spec/enterprise/services/whatsapp/call_service_spec.rb index fdcf154eb..53c4b1f8d 100644 --- a/spec/enterprise/services/whatsapp/call_service_spec.rb +++ b/spec/enterprise/services/whatsapp/call_service_spec.rb @@ -68,6 +68,14 @@ describe Whatsapp::CallService do expect { described_class.new(call: call, agent: agent, sdp_answer: nil).accept } .to raise_error(Voice::CallErrors::CallFailed, 'sdp_answer is required') end + + it 'wraps Meta transport exceptions as CallFailed and leaves the call ringing' do + allow(provider_service).to receive(:pre_accept_call).and_raise(Faraday::TimeoutError) + + expect { described_class.new(call: call, agent: agent, sdp_answer: sdp_answer).accept } + .to raise_error(Voice::CallErrors::CallFailed) + expect(call.reload.status).to eq('ringing') + end end describe '#reject' do