diff --git a/lib/session/call-session.js b/lib/session/call-session.js index 06ee486d..1d939a2d 100644 --- a/lib/session/call-session.js +++ b/lib/session/call-session.js @@ -33,7 +33,7 @@ const BackgroundTaskManager = require('../utils/background-task-manager'); const dbUtils = require('../utils/db-utils'); const BADPRECONDITIONS = 'preconditions not met'; const CALLER_CANCELLED_ERR_MSG = 'Response not sent due to unknown transaction'; - +const { NonFatalTaskError} = require('../utils/error'); const sqlRetrieveQueueEventHook = `SELECT * FROM webhooks WHERE webhook_sid = ( @@ -1092,6 +1092,8 @@ class CallSession extends Emitter { this.currentTask = null; if (err.message?.includes(BADPRECONDITIONS)) { this.logger.info(`CallSession:exec task #${stackNum}:${taskNum}: ${task.name}: ${err.message}`); + } else if (err instanceof NonFatalTaskError) { + this.logger.error(err, `Error executing task #${stackNum}:${taskNum}: ${task.name}`); } else { this.logger.error(err, `Error executing task #${stackNum}:${taskNum}: ${task.name}`); diff --git a/lib/tasks/play.js b/lib/tasks/play.js index eae0bbb6..8e2ee956 100644 --- a/lib/tasks/play.js +++ b/lib/tasks/play.js @@ -1,5 +1,6 @@ const Task = require('./task'); const {TaskName, TaskPreconditions} = require('../utils/constants'); +const { PlayFileNotFoundError } = require('../utils/error'); class TaskPlay extends Task { constructor(logger, opts) { @@ -66,8 +67,20 @@ class TaskPlay extends Task { } } } catch (err) { - if (timeout) clearTimeout(timeout); - this.logger.info(err, `TaskPlay:exec - error playing ${this.url}`); + this.logger.info(`TaskPlay:exec - error playing ${this.url}: ${err.message}`); + this.playComplete = true; + if (err.message === 'File Not Found') { + const {writeAlerts, AlertType} = cs.srf.locals; + await this.performAction({status: 'fail', reason: 'playFailed'}, !(this.parentTask || cs.isConfirmCallSession)); + this.emit('playDone'); + writeAlerts({ + account_sid: cs.accountSid, + alert_type: AlertType.PLAY_FILENOTFOUND, + url: this.url, + target_sid: cs.callSid + }); + throw new PlayFileNotFoundError(this.url); + } } this.emit('playDone'); } diff --git a/lib/utils/action-hook-delay.js b/lib/utils/action-hook-delay.js index 839e38f1..4b18ae3c 100644 --- a/lib/utils/action-hook-delay.js +++ b/lib/utils/action-hook-delay.js @@ -126,7 +126,12 @@ class ActionHookDelayProcessor extends Emitter { try { this._taskInProgress = makeTask(this.logger, t[0]); this._taskInProgress.disableTracing = true; - this._taskInProgress.exec(this.cs, {ep: this.ep}); + this._taskInProgress.exec(this.cs, {ep: this.ep}).catch((err) => { + this.logger.info(`ActionHookDelayProcessor#_onNoResponseTimer: error playing file: ${err.message}`); + this._taskInProgress = null; + this.ep.removeAllListeners('playback-start'); + this.ep.removeAllListeners('playback-stop'); + }); } catch (err) { this.logger.info(err, 'ActionHookDelayProcessor#_onNoResponseTimer: error starting action'); this._taskInProgress = null; diff --git a/lib/utils/error.js b/lib/utils/error.js index 7b47cf17..c6964a67 100644 --- a/lib/utils/error.js +++ b/lib/utils/error.js @@ -1,9 +1,24 @@ -class SpeechCredentialError extends Error { +class NonFatalTaskError extends Error { constructor(msg) { super(msg); } } +class SpeechCredentialError extends NonFatalTaskError { + constructor(msg) { + super(msg); + } +} + +class PlayFileNotFoundError extends NonFatalTaskError { + constructor(url) { + super('File not found'); + this.url = url; + } +} + module.exports = { - SpeechCredentialError + SpeechCredentialError, + NonFatalTaskError, + PlayFileNotFoundError }; diff --git a/package-lock.json b/package-lock.json index f770585f..1b561e71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@jambonz/realtimedb-helpers": "^0.8.8", "@jambonz/speech-utils": "^0.1.22", "@jambonz/stats-collector": "^0.1.10", - "@jambonz/time-series": "^0.2.9", + "@jambonz/time-series": "^0.2.12", "@jambonz/verb-specifications": "^0.0.86", "@opentelemetry/api": "^1.8.0", "@opentelemetry/exporter-jaeger": "^1.23.0", @@ -31,7 +31,7 @@ "bent": "^7.3.12", "debug": "^4.3.4", "deepcopy": "^2.1.0", - "drachtio-fsmrf": "^3.0.45", + "drachtio-fsmrf": "^3.0.46", "drachtio-srf": "^4.5.35", "express": "^4.19.2", "express-validator": "^7.0.1", @@ -1572,9 +1572,10 @@ } }, "node_modules/@jambonz/time-series": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.9.tgz", - "integrity": "sha512-+/Oal0mjjV4iQ8q0ymtvVJP+GqgGpYUb2bc/FD/xDxOzKtl340l9yoM3oczREJg5IvEkpExz6NogJzUiCSeVnQ==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.12.tgz", + "integrity": "sha512-EYw5f1QasblWrP2K/NabpJYkQm8XOCP1fem8luO8c7Jm8YTBwI+Ge3zB7rpU8ruoVdbrTot/pcihhTqzq4IYqA==", + "license": "MIT", "dependencies": { "debug": "^4.3.1", "influx": "^5.9.3" @@ -3877,9 +3878,10 @@ } }, "node_modules/drachtio-fsmrf": { - "version": "3.0.45", - "resolved": "https://registry.npmjs.org/drachtio-fsmrf/-/drachtio-fsmrf-3.0.45.tgz", - "integrity": "sha512-YsrevTwGvg9v0OQXB4gZedlmzegB83fyd3NX3X2x7NXsKa5jO6TZCvZVHtBf/jR/ELE3B0aVLpxHw2YviRMIuQ==", + "version": "3.0.46", + "resolved": "https://registry.npmjs.org/drachtio-fsmrf/-/drachtio-fsmrf-3.0.46.tgz", + "integrity": "sha512-ScgyOnsOL45feuKKquT2Gij/jDRdjVha2TnQ6/Me2/M/C+29c9W7cdYlt3UZB3GyodazBukwIy5RrZf1iuXBGw==", + "license": "MIT", "dependencies": { "camel-case": "^4.1.2", "debug": "^2.6.9", @@ -10742,9 +10744,9 @@ } }, "@jambonz/time-series": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.9.tgz", - "integrity": "sha512-+/Oal0mjjV4iQ8q0ymtvVJP+GqgGpYUb2bc/FD/xDxOzKtl340l9yoM3oczREJg5IvEkpExz6NogJzUiCSeVnQ==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.12.tgz", + "integrity": "sha512-EYw5f1QasblWrP2K/NabpJYkQm8XOCP1fem8luO8c7Jm8YTBwI+Ge3zB7rpU8ruoVdbrTot/pcihhTqzq4IYqA==", "requires": { "debug": "^4.3.1", "influx": "^5.9.3" @@ -12464,9 +12466,9 @@ } }, "drachtio-fsmrf": { - "version": "3.0.45", - "resolved": "https://registry.npmjs.org/drachtio-fsmrf/-/drachtio-fsmrf-3.0.45.tgz", - "integrity": "sha512-YsrevTwGvg9v0OQXB4gZedlmzegB83fyd3NX3X2x7NXsKa5jO6TZCvZVHtBf/jR/ELE3B0aVLpxHw2YviRMIuQ==", + "version": "3.0.46", + "resolved": "https://registry.npmjs.org/drachtio-fsmrf/-/drachtio-fsmrf-3.0.46.tgz", + "integrity": "sha512-ScgyOnsOL45feuKKquT2Gij/jDRdjVha2TnQ6/Me2/M/C+29c9W7cdYlt3UZB3GyodazBukwIy5RrZf1iuXBGw==", "requires": { "camel-case": "^4.1.2", "debug": "^2.6.9", diff --git a/package.json b/package.json index b69b4ce5..e619b269 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@jambonz/realtimedb-helpers": "^0.8.8", "@jambonz/speech-utils": "^0.1.22", "@jambonz/stats-collector": "^0.1.10", - "@jambonz/time-series": "^0.2.9", + "@jambonz/time-series": "^0.2.12", "@jambonz/verb-specifications": "^0.0.86", "@opentelemetry/api": "^1.8.0", "@opentelemetry/exporter-jaeger": "^1.23.0", @@ -47,7 +47,7 @@ "bent": "^7.3.12", "debug": "^4.3.4", "deepcopy": "^2.1.0", - "drachtio-fsmrf": "^3.0.45", + "drachtio-fsmrf": "^3.0.46", "drachtio-srf": "^4.5.35", "express": "^4.19.2", "express-validator": "^7.0.1",