Hi @davehorton
Handling Silent/Blank Calls Due to Freeswitch or TTS Failures
It is important that calls do not go blank when audio is not played or when FreeSWITCH encounters an error. We must ensure the bot can detect these issues and take corrective action (e.g., transfer the call to an external system). Below are the failure scenarios and expected behaviors.
Failure Scenarios
- FreeSWITCH restart
When FreeSWITCH restarts unexpectedly, the media engine stops responding.
This must trigger jambonz:error so the bot can decide the next action (usually: transfer the call).
- HTTP URL (audio file) DNS failure or no timeout from HTTP server
If the HTTP URL used for audio is not reachable or does not timeout properly, playback never begins.
This should raise a jambonz:error with an appropriate error type (e.g., audio-fetch-timeout or audio-url-unreachable).
- Issues with FreeSWITCH module loading
Module not loaded or wrong module name (e.g., mod_tts_engine not present).
Must raise jambonz:error with type such as fs-module-missing.
- Zero-byte TTS response after successful 200 OK
This can happen for two reasons:
User passes empty text → engine returns 0-byte audio
Engine closes connection unexpectedly → real TTS engine error
Behavior differences:
Case A: Empty text / benign 0-byte audio
Call should continue normally.
No jambonz:error.
Need to inspect WSS close code to confirm this is not an error.
Case B: Real TTS engine failure
WSS socket closes with an error code.
Must raise jambonz:error with type tts-error.
- Channel lock due to mutex (“play promise never resolves”)
This must be treated as a playback failure.
→ Should throw jambonz:error with type play-no-response.
Could have timeout set for tts playback start
At https://github.com/jambonz/jambonz-feature-server/blob/main/lib/tasks/say.js#L415 the system will go in wait state after issuing the play command on the endpoint, if for any reason, playback-stop is not received from freeswitch, the entire call be in continuous waiting mode, because the promise will be resolved in playback-stop event.
We should have a configurable timeout, using which if we don't receive the playback-start event in this time period, then the promise should be resolved. We need to check for not receiving the playback-start because playback-stop is registered inside playback-start
@rammohan-y @oddsix
Hi @davehorton
Handling Silent/Blank Calls Due to Freeswitch or TTS Failures
It is important that calls do not go blank when audio is not played or when FreeSWITCH encounters an error. We must ensure the bot can detect these issues and take corrective action (e.g., transfer the call to an external system). Below are the failure scenarios and expected behaviors.
Failure Scenarios
When FreeSWITCH restarts unexpectedly, the media engine stops responding.
This must trigger jambonz:error so the bot can decide the next action (usually: transfer the call).
If the HTTP URL used for audio is not reachable or does not timeout properly, playback never begins.
This should raise a jambonz:error with an appropriate error type (e.g., audio-fetch-timeout or audio-url-unreachable).
Module not loaded or wrong module name (e.g., mod_tts_engine not present).
Must raise jambonz:error with type such as fs-module-missing.
This can happen for two reasons:
User passes empty text → engine returns 0-byte audio
Engine closes connection unexpectedly → real TTS engine error
Behavior differences:
Case A: Empty text / benign 0-byte audio
Call should continue normally.
No jambonz:error.
Need to inspect WSS close code to confirm this is not an error.
Case B: Real TTS engine failure
WSS socket closes with an error code.
Must raise jambonz:error with type tts-error.
This must be treated as a playback failure.
→ Should throw jambonz:error with type play-no-response.
Could have timeout set for tts playback start
At https://github.com/jambonz/jambonz-feature-server/blob/main/lib/tasks/say.js#L415 the system will go in wait state after issuing the play command on the endpoint, if for any reason, playback-stop is not received from freeswitch, the entire call be in continuous waiting mode, because the promise will be resolved in playback-stop event.
We should have a configurable timeout, using which if we don't receive the playback-start event in this time period, then the promise should be resolved. We need to check for not receiving the playback-start because playback-stop is registered inside playback-start
@rammohan-y @oddsix