feat: abort call on pipeline error and send rtf event

This commit is contained in:
Abhishek Kumar 2026-03-05 14:51:39 +05:30
parent 1614879ddd
commit dfb741e475
9 changed files with 86 additions and 10 deletions

View file

@ -3,6 +3,7 @@ from loguru import logger
from api.db import db_client
from api.enums import WorkflowRunState
from api.services.campaign.campaign_call_dispatcher import campaign_call_dispatcher
from api.services.campaign.circuit_breaker import circuit_breaker
from api.services.pipecat.audio_config import AudioConfig
from api.services.pipecat.in_memory_buffers import (
InMemoryAudioBuffer,
@ -95,6 +96,22 @@ def register_event_handlers(
ready_state["pipeline_started"] = True
await maybe_trigger_llm()
@task.event_handler("on_pipeline_error")
async def on_pipeline_error(_task: PipelineTask, frame: Frame):
logger.warning(f"Pipeline error for workflow run {workflow_run_id}: {frame}")
try:
workflow_run = await db_client.get_workflow_run_by_id(workflow_run_id)
if workflow_run and workflow_run.campaign_id:
await circuit_breaker.record_and_evaluate(
campaign_id=workflow_run.campaign_id, is_failure=True
)
except Exception as e:
logger.error(f"Error recording circuit breaker failure: {e}", exc_info=True)
await engine.end_call_with_reason(
EndTaskReason.PIPELINE_ERROR.value, abort_immediately=True
)
@task.event_handler("on_pipeline_finished")
async def on_pipeline_finished(
task: PipelineTask,

View file

@ -32,6 +32,7 @@ if TYPE_CHECKING:
from pipecat.frames.frames import (
CancelFrame,
EndFrame,
ErrorFrame,
FunctionCallInProgressFrame,
FunctionCallResultFrame,
InterimTranscriptionFrame,
@ -272,6 +273,19 @@ class RealtimeFeedbackObserver(BaseObserver):
},
}
)
# Handle pipeline errors
elif isinstance(frame, ErrorFrame):
processor_name = str(frame.processor) if frame.processor else None
await self._send_message(
{
"type": RealtimeFeedbackType.PIPELINE_ERROR.value,
"payload": {
"error": frame.error,
"fatal": frame.fatal,
"processor": processor_name,
},
}
)
async def _send_ws(self, message: dict):
"""Send message via WebSocket only, handling errors gracefully."""

View file

@ -536,10 +536,11 @@ class PipecatEngine:
# Mute the pipeline
self._mute_pipeline = True
# Perform final variable extraction synchronously before ending
await self._perform_variable_extraction_if_needed(
self._current_node, run_in_background=False
)
if reason != EndTaskReason.PIPELINE_ERROR.value:
# Perform final variable extraction synchronously before ending
await self._perform_variable_extraction_if_needed(
self._current_node, run_in_background=False
)
frame_to_push = (
CancelFrame(reason=reason) if abort_immediately else EndFrame(reason=reason)