@babblevoice/babble-drachtio-callmanager 3.6.9 → 3.6.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/call.js CHANGED
@@ -52,6 +52,21 @@ function keynameslower( obj ) {
52
52
  }, {} )
53
53
  }
54
54
 
55
+ /**
56
+ * @summary Finds the correct key in a case-insensitive manner and retrieves the key and value.
57
+ * @param {Object} headers - The headers object.
58
+ * @param {string} targetKey - The key to search for.
59
+ * @return {Object|undefined} - Returns an object with the correct key and value, or undefined if not found.
60
+ */
61
+ function getheadervalue( headers, targetKey ) {
62
+ const lowerCaseTargetKey = targetKey.toLowerCase()
63
+ for(const key in headers) {
64
+ if( key.toLowerCase() === lowerCaseTargetKey) {
65
+ return { key, value: headers[key] }
66
+ }
67
+ }
68
+ }
69
+
55
70
  /*
56
71
  Enum for different reasons for hangup.
57
72
  */
@@ -173,6 +188,7 @@ class call {
173
188
  "trying": false,
174
189
  "early": false,
175
190
  "ringing": false,
191
+ "establishing": false, /** we have received 200 but we send ack - late neg only */
176
192
  "established": false,
177
193
  "canceled": false,
178
194
  "destroyed": false,
@@ -364,6 +380,8 @@ class call {
364
380
  * @type { string }
365
381
  */
366
382
  this.referingtouri
383
+
384
+ this.errors = []
367
385
  }
368
386
 
369
387
  /**
@@ -1207,26 +1225,30 @@ class call {
1207
1225
  */
1208
1226
  async _onearly() {
1209
1227
 
1210
- if( this.state.established ) return
1211
- if( !this._res || !this._res.msg || !this._res.msg.body ) return
1212
-
1213
- /* we have this._res */
1214
- this.sdp.remote = sdpgen.create( this._res.msg.body )
1215
- this.#parsesrtpsetup()
1216
- await this.answer( { "early": true } )
1217
-
1218
- if( !this.parent || this.parent.state.established ) return
1219
-
1220
- await this.parent.answer( { "early": true } )
1221
- await this.channels.audio.mix( this.parent.channels.audio )
1222
-
1223
- this.parent._res.send( 183, {
1224
- headers: {
1225
- "User-Agent": "project",
1226
- "Supported": "replaces"
1227
- },
1228
- "body": this.parent.sdp.local.toString()
1229
- } )
1228
+ try {
1229
+ if( this.state.established ) return
1230
+ if( !this._res || !this._res.msg || !this._res.msg.body ) return
1231
+
1232
+ /* we have this._res */
1233
+ this.sdp.remote = sdpgen.create( this._res.msg.body )
1234
+ this.#parsesrtpsetup()
1235
+ await this.answer( { "early": true } )
1236
+
1237
+ if( !this.parent || this.parent.state.established ) return
1238
+
1239
+ await this.parent.answer( { "early": true } )
1240
+ await this.channels.audio.mix( this.parent.channels.audio )
1241
+
1242
+ this.parent._res.send( 183, {
1243
+ headers: {
1244
+ "User-Agent": "project",
1245
+ "Supported": "replaces"
1246
+ },
1247
+ "body": this.parent.sdp.local.toString()
1248
+ } )
1249
+ } catch( e ) {
1250
+ throw new Error( e )
1251
+ }
1230
1252
  }
1231
1253
 
1232
1254
  async #answerparent() {
@@ -1329,7 +1351,7 @@ class call {
1329
1351
  await this.#openrelatedchannel( channeldef )
1330
1352
 
1331
1353
  if ( !this.channels.audio ) {
1332
- this.hangup( hangupcodes.SERVER_ERROR )
1354
+ this.#servererror( "Failed to open channel" )
1333
1355
  return
1334
1356
  }
1335
1357
 
@@ -1351,7 +1373,8 @@ class call {
1351
1373
  .rtcpmux()
1352
1374
  }
1353
1375
 
1354
- this.#setdialog( await this._dialog.ack( this.sdp.local.toString() ) )
1376
+ this._dialog = await this._dialog.ack( this.sdp.local.toString() )
1377
+ this.established = true
1355
1378
  this._addevents( this._dialog )
1356
1379
 
1357
1380
  await this.#answerparent()
@@ -1666,7 +1689,7 @@ class call {
1666
1689
 
1667
1690
  await this.#openrelatedchannel( channeldef )
1668
1691
  if( !this.channels.audio ) {
1669
- this.hangup( hangupcodes.SERVER_ERROR )
1692
+ this.#servererror( "Failed to open channel" )
1670
1693
  return
1671
1694
  }
1672
1695
 
@@ -1720,6 +1743,10 @@ class call {
1720
1743
  if( this.canceled || this.established ) return
1721
1744
 
1722
1745
  await this.#choosecodecforanswer()
1746
+ if( !this.channels.audio ) {
1747
+ this.#servererror( "Failed to open channel" )
1748
+ return
1749
+ }
1723
1750
 
1724
1751
  if( this.canceled ) return
1725
1752
 
@@ -1730,7 +1757,7 @@ class call {
1730
1757
  } else {
1731
1758
 
1732
1759
  if ( !this.sdp.local ) {
1733
- this.hangup( hangupcodes.SERVER_ERROR )
1760
+ this.#servererror( "No local SDP" )
1734
1761
  return
1735
1762
  }
1736
1763
 
@@ -2155,25 +2182,10 @@ class call {
2155
2182
  @private
2156
2183
  */
2157
2184
  async mix( othercall ) {
2158
- if ( othercall.channels.audio
2159
- && othercall.channels.audio.connection.instance
2160
- != this.channels.audio.connection.instance ) {
2161
-
2162
- const channeldef = await othercall.#createchannelremotedef()
2163
-
2164
- const oldchannel = othercall.channels.audio
2165
- const newchannel = await this.#openchannel( channeldef, othercall )
2166
- if( !newchannel ) {
2167
- this.hangup( hangupcodes.SERVER_ERROR )
2168
- return
2169
- }
2170
-
2171
- await othercall.bond( this ).reinvite( channeldef, newchannel )
2172
-
2173
- await oldchannel.unmix()
2174
- oldchannel.close()
2175
- }
2185
+ if( !othercall.channels.audio ) return
2186
+ if( !this.channels.audio ) return
2176
2187
 
2188
+ await this.#mixdifferentnode( othercall )
2177
2189
  await this.channels.audio.mix( othercall.channels.audio )
2178
2190
 
2179
2191
  this._em.emit( "call.mix", this )
@@ -2185,6 +2197,51 @@ class call {
2185
2197
  othercall.epochs.mix = Math.floor( +new Date() / 1000 )
2186
2198
  }
2187
2199
 
2200
+ /**
2201
+ * hangs up and throws exception to get out
2202
+ * @param { string } reason
2203
+ */
2204
+ #servererror( reason ) {
2205
+ this.hangup( hangupcodes.SERVER_ERROR )
2206
+ this.errors.push( { now: +new Date(), reason } )
2207
+
2208
+ const ourerror = Error( reason )
2209
+ // @ts-ignore
2210
+ ourerror.normalandsilent = true
2211
+ throw ourerror
2212
+ }
2213
+
2214
+ /**
2215
+ *
2216
+ * @param { call } othercall
2217
+ * @returns { Promise }
2218
+ */
2219
+ async #mixdifferentnode( othercall ) {
2220
+
2221
+ if( !othercall.channels.audio.connection ) return
2222
+ if( !othercall.channels.audio.connection.instance ) return
2223
+
2224
+ if( !this.channels.audio.connection ) return
2225
+ if( !this.channels.audio.connection.instance ) return
2226
+
2227
+ if( othercall.channels.audio.connection.instance == this.channels.audio.connection.instance ) return
2228
+
2229
+ const channeldef = await othercall.#createchannelremotedef()
2230
+
2231
+ const oldchannel = othercall.channels.audio
2232
+ const newchannel = await this.#openchannel( channeldef, othercall )
2233
+ if( !newchannel ) {
2234
+ this.#servererror( "Failed to open channel" )
2235
+ return
2236
+ }
2237
+
2238
+ await othercall.bond( this ).reinvite( channeldef, newchannel )
2239
+
2240
+ await oldchannel.unmix()
2241
+ oldchannel.close()
2242
+
2243
+ }
2244
+
2188
2245
  /**
2189
2246
  Mix two calls. If the two calls are on a different node
2190
2247
  the second call is bonded and reinvited.
@@ -2193,22 +2250,29 @@ class call {
2193
2250
  */
2194
2251
  async #openchannel( channeldef, bindcall ) {
2195
2252
 
2196
- let chan = undefined
2253
+ try {
2254
+ let chan
2255
+ let bind
2256
+ if( bindcall ) bind = bindcall
2257
+ else bind = this
2258
+
2259
+ if ( this.channels.audio ) {
2260
+ chan = await this.channels.audio.openchannel(
2261
+ channeldef, bind._handlechannelevents.bind( bind ) )
2262
+ } else {
2263
+ chan = await projectrtp.openchannel(
2264
+ channeldef, bind._handlechannelevents.bind( bind ) )
2265
+ }
2197
2266
 
2198
- if ( !bindcall || !this.channels.audio ) {
2199
- chan = await projectrtp.openchannel(
2200
- channeldef, this._handlechannelevents.bind( this ) )
2201
- } else {
2202
- chan = await this.channels.audio.openchannel(
2203
- channeldef, bindcall._handlechannelevents.bind( bindcall ) )
2267
+ bind.channels.count++
2268
+
2269
+ return chan
2270
+ } catch( e ) {
2271
+ if( this.channels.audio )
2272
+ console.trace( "problem opening channel on related channel", e )
2273
+ else
2274
+ console.trace( "problem opening channel on prtp", e )
2204
2275
  }
2205
-
2206
- if ( bindcall )
2207
- bindcall.channels.count++
2208
- else
2209
- this.channels.count++
2210
-
2211
- return chan
2212
2276
  }
2213
2277
 
2214
2278
  /**
@@ -2527,7 +2591,7 @@ class call {
2527
2591
  b_1.channels.audio.unmix()
2528
2592
  await b_1.waitforanyevent( { "action": "mix", "event": "finished" }, 0.5 )
2529
2593
  }
2530
- b_1.hangup( b_1.hangupcodes.ATTENDED_TRANSFER )
2594
+ b_1.hangup( hangupcodes.ATTENDED_TRANSFER )
2531
2595
  }
2532
2596
 
2533
2597
  /**
@@ -2758,7 +2822,14 @@ class call {
2758
2822
  async #createchannelremotedef() {
2759
2823
 
2760
2824
  const iswebrtc = this._iswebrtc
2761
- const target = await this.#getremotetarget( iswebrtc )
2825
+
2826
+ let target
2827
+ try{
2828
+ target = await this.#getremotetarget( iswebrtc )
2829
+ } catch( e ) {
2830
+ throw new Error( e )
2831
+ }
2832
+
2762
2833
 
2763
2834
  if( !target ) return
2764
2835
  const address = target.address
@@ -2856,7 +2927,7 @@ class call {
2856
2927
  callmanager.options.em.emit( "call.reporting", this )
2857
2928
 
2858
2929
  return 0
2859
- } ).catch( () => {} )
2930
+ } ).catch( ( e ) => { console.error( e ) } )
2860
2931
  }
2861
2932
 
2862
2933
  /**
@@ -2883,7 +2954,6 @@ class call {
2883
2954
  */
2884
2955
  // eslint-disable-next-line complexity
2885
2956
  async _onhangup( src = "us", reason ) {
2886
-
2887
2957
  if( this._state._onhangup ) {
2888
2958
  await this.waitforhangup()
2889
2959
  return
@@ -2891,32 +2961,7 @@ class call {
2891
2961
  this._state._onhangup = true
2892
2962
 
2893
2963
  this._sethangupcause( src, reason )
2894
-
2895
- if( "wire" == src ) {
2896
- /*
2897
- 1. Hangup our children regardless of our state
2898
- 2. If we are established and the only child child - hangup our parent (unless otherwise told not to: parent.continueonotherhangup)
2899
- */
2900
- const hangups = []
2901
- if( this.options.hangupchildrenonhangup ) {
2902
- for( const child of this.children ) {
2903
- if( !child.options.continueonotherhangup ) {
2904
- hangups.push( child.hangup( this.hangup_cause ) )
2905
- }
2906
- }
2907
- }
2908
-
2909
- if( this.established && this.options.hangupparentonhangup && this.parent ) {
2910
- if( !this.parent.options.continueonotherhangup && 2 > this.parent.children.size ) {
2911
- hangups.push( this.parent.hangup( this.hangup_cause ) )
2912
- }
2913
- }
2914
-
2915
- /* wait for all relatives to complete their hangup */
2916
- if( 0 < hangups.length ) {
2917
- await Promise.all( hangups )
2918
- }
2919
- }
2964
+ await this.#handlewirehangup( src )
2920
2965
 
2921
2966
  /* flag destroyed so when we receive our close event we know what to do */
2922
2967
  this.destroyed = true
@@ -2928,11 +2973,69 @@ class call {
2928
2973
  an event on the event listener so we can safely return here and not call _cleanup */
2929
2974
  if( "object" == typeof cl ) return
2930
2975
  } catch( e ) {
2931
- console.error( "timed out waiting for channel close" )
2976
+ console.error( "timed out waiting for channel close", e )
2932
2977
  }
2933
2978
  }
2934
2979
 
2935
- this._cleanup()
2980
+ try {
2981
+ this._cleanup()
2982
+ } catch( e ) {
2983
+ throw new Error( e )
2984
+ }
2985
+ }
2986
+
2987
+ /**
2988
+ *
2989
+ * @param { "us"|"wire" } src
2990
+ * @returns
2991
+ */
2992
+ async #handlewirehangup( src ) {
2993
+
2994
+ if( "wire" != src ) return
2995
+
2996
+ /*
2997
+ 1. Hangup our children regardless of our state
2998
+ 2. If we are established and the only child child - hangup our parent (unless otherwise told not to: parent.continueonotherhangup)
2999
+ */
3000
+ const hangups = this.#hangupchildren()
3001
+ this.#hangupparent( hangups )
3002
+
3003
+ /* wait for all relatives to complete their hangup */
3004
+ if( 0 < hangups.length ) {
3005
+ try{
3006
+ await Promise.all( hangups )
3007
+ } catch( e ) {
3008
+ throw new Error( e )
3009
+ }
3010
+ }
3011
+ }
3012
+
3013
+ /**
3014
+ * If options allow hangup parent
3015
+ * @param { Array } hangups
3016
+ */
3017
+ #hangupparent( hangups ) {
3018
+ if( this.established && this.options.hangupparentonhangup && this.parent ) {
3019
+ if( !this.parent.options.continueonotherhangup && 2 > this.parent.children.size ) {
3020
+ hangups.push( this.parent.hangup( this.hangup_cause ) )
3021
+ }
3022
+ }
3023
+ }
3024
+
3025
+ /**
3026
+ * If options allow - hangup other children
3027
+ * @returns { Array< Promise > }
3028
+ */
3029
+ #hangupchildren() {
3030
+ const hangups = []
3031
+ if( this.options.hangupchildrenonhangup ) {
3032
+ for( const child of this.children ) {
3033
+ if( !child.options.continueonotherhangup ) {
3034
+ hangups.push( child.hangup( this.hangup_cause ) )
3035
+ }
3036
+ }
3037
+ }
3038
+ return hangups
2936
3039
  }
2937
3040
 
2938
3041
  /**
@@ -2943,29 +3046,61 @@ class call {
2943
3046
  *
2944
3047
  */
2945
3048
  async hangup( reason, tone = false, source = "us" ) {
3049
+ try {
3050
+ if( this._state._hangup || this._state._onhangup ) {
3051
+ await this.waitforhangup()
3052
+ return
3053
+ }
2946
3054
 
2947
- if( this._state._hangup || this._state._onhangup ) {
2948
- await this.waitforhangup()
2949
- return
3055
+ this._sethangupcause( source, reason )
3056
+ this._state._hangup = true
3057
+ if( this.state.established ) {
3058
+ if( this.#hangupestablish( reason, tone ) ) return
3059
+ } else if( "uac" === this.type && this.state.trying ) {
3060
+ this.#hangupnotestablish()
3061
+ await this._onhangup( source, reason )
3062
+ return
3063
+ } else if( this._res ) {
3064
+ this._res.send( this.hangup_cause.sip )
3065
+ await this._onhangup( source, reason )
3066
+ return
3067
+ }
3068
+
3069
+ await this.#destroydialog()
3070
+ } catch( e ) {
3071
+ console.trace( e )
2950
3072
  }
2951
3073
 
2952
- this._sethangupcause( source, reason )
3074
+ await this._onhangup( source, reason )
3075
+ }
2953
3076
 
2954
- if( this.state.established ) {
2955
- if( this.#hangupestablish( reason, tone ) ) return
2956
- } else if( "uac" === this.type && this.state.trying ) {
2957
- this.#hangupnotestablish()
2958
- } else if( this._res ) {
2959
- this._res.send( this.hangup_cause.sip )
2960
- }
3077
+ /**
3078
+ *
3079
+ * @returns { Promise }
3080
+ */
3081
+ async #destroydialog() {
3082
+ if( !this._dialog ) return
3083
+ if( !this._dialog.destroy ) return
2961
3084
 
2962
- this._state._hangup = true
3085
+ await this._dialog.destroy()
3086
+ }
2963
3087
 
2964
- try {
2965
- if( this._dialog ) await this._dialog.destroy()
2966
- } catch( e ) { console.trace( e ) }
3088
+ /**
3089
+ * We have played a tone - give it a limit.
3090
+ */
3091
+ #scheduledelayedhangup() {
2967
3092
 
2968
- await this._onhangup( source, reason )
3093
+ this._timers.delayedhangup = setTimeout( async () => {
3094
+ if( this._state._onhangup ) return
3095
+ try {
3096
+ await this.#destroydialog()
3097
+ } catch ( e ) {
3098
+ console.trace( e )
3099
+ }
3100
+
3101
+ await this._onhangup()
3102
+
3103
+ }, 5000 )
2969
3104
  }
2970
3105
 
2971
3106
  /**
@@ -2973,19 +3108,30 @@ class call {
2973
3108
  * @param { boolean } tone
2974
3109
  */
2975
3110
  #hangupestablish( reason, tone ) {
2976
- if( undefined != reason && tone ) {
2977
- switch( reason.sip ) {
2978
- case 486:
2979
- this.play( this.engagedsoup )
2980
- return true
2981
- case 480:
2982
- this.play( this.unobtainablesoup )
2983
- return true
2984
- }
3111
+ if( !reason ) return false
3112
+ if( !tone ) return false
3113
+ if( "object" != typeof reason ) return false
3114
+
3115
+ switch( reason.sip ) {
3116
+ case 486:
3117
+ this._state._hangup = false
3118
+ this.play( this.engagedsoup )
3119
+ this.#scheduledelayedhangup()
3120
+ return true
3121
+ case 480:
3122
+ this._state._hangup = false
3123
+ this.play( this.unobtainablesoup )
3124
+ this.#scheduledelayedhangup()
3125
+ return true
2985
3126
  }
3127
+
2986
3128
  return false
3129
+
2987
3130
  }
2988
3131
 
3132
+ /**
3133
+ * The call is not established so send a cancel.
3134
+ */
2989
3135
  #hangupnotestablish() {
2990
3136
  try {
2991
3137
  this.canceled = true
@@ -3071,19 +3217,21 @@ class call {
3071
3217
  */
3072
3218
  async newuac( options, callbacks = {} ) {
3073
3219
 
3074
- /* If max-forwards is not specified then we decrement the parent and pass on */
3075
3220
  if( !( "headers" in options ) ) options.headers = {}
3221
+ /* If max-forwards is not specified then we decrement the parent and pass on */
3222
+
3223
+ const ouroptionsmaxforwards = getheadervalue( options.headers, "max-forwards" )
3224
+ const ourimportsmaxforwards = getheadervalue( this.propagate.headers, "max-forwards" )
3076
3225
 
3077
- let maxforwards = 70
3078
- if( !options.headers[ Object.keys( options.headers ).find( key => "max-forwards" === key.toLowerCase() ) ] ) {
3226
+ if( !ouroptionsmaxforwards && !ourimportsmaxforwards ) {
3227
+ let maxforwards = 70
3079
3228
  if( this._req.has( "Max-Forwards" ) ) {
3080
3229
  maxforwards = parseInt( this._req.get( "Max-Forwards" ) ) - 1
3081
3230
  if( isNaN( maxforwards ) || 0 >= maxforwards ) return false
3082
3231
  }
3232
+ options.headers[ "max-forwards" ] = maxforwards
3083
3233
  }
3084
3234
 
3085
- options.headers[ "max-forwards" ] = maxforwards
3086
-
3087
3235
  if( !options.orphan && !options.parent ) {
3088
3236
  options.parent = this
3089
3237
  }
@@ -3201,26 +3349,30 @@ class call {
3201
3349
  */
3202
3350
  async #openrelatedchannel( channeldef ) {
3203
3351
 
3204
- if( this.channels.audio ) return
3205
-
3206
- const othercall = this.other
3207
- /* TODO: this is a hack. projectrtp has become too complicated with both a listen and connect
3208
- mechanism. This is causing problems in code like this. There is no interface to
3209
- detect which mode the channel is in - but the channels property will exist on a connect
3210
- style channel. projectrtp will getrelatives a rewrite to support only one. */
3211
- if( othercall && othercall.channels.audio ) {
3212
- this.channels.audio = await othercall.#openchannel( channeldef, this )
3213
- return
3214
- }
3352
+ try {
3353
+ if( this.channels.audio ) return
3215
3354
 
3216
- for( const other of this.relatives ) {
3217
- if( other.channels && other.channels.audio ) {
3218
- this.channels.audio = await other.#openchannel( channeldef, this )
3355
+ const othercall = this.other
3356
+ /* TODO: this is a hack. projectrtp has become too complicated with both a listen and connect
3357
+ mechanism. This is causing problems in code like this. There is no interface to
3358
+ detect which mode the channel is in - but the channels property will exist on a connect
3359
+ style channel. projectrtp will getrelatives a rewrite to support only one. */
3360
+ if( othercall && othercall.channels.audio ) {
3361
+ this.channels.audio = await othercall.#openchannel( channeldef, this )
3219
3362
  return
3220
3363
  }
3364
+
3365
+ for( const other of this.relatives ) {
3366
+ if( other.channels && other.channels.audio ) {
3367
+ this.channels.audio = await other.#openchannel( channeldef, this )
3368
+ return
3369
+ }
3370
+ }
3371
+
3372
+ this.channels.audio = await this.#openchannel( channeldef )
3373
+ } catch( e ) {
3374
+ console.trace( e )
3221
3375
  }
3222
-
3223
- this.channels.audio = await this.#openchannel( channeldef )
3224
3376
  }
3225
3377
 
3226
3378
  /**
@@ -3247,7 +3399,7 @@ class call {
3247
3399
 
3248
3400
  await this.#openrelatedchannel( channeldef )
3249
3401
  if( !this.channels.audio ) {
3250
- this.hangup( hangupcodes.SERVER_ERROR )
3402
+ this.#servererror( "Failed to open channel" )
3251
3403
  return
3252
3404
  }
3253
3405
 
@@ -3308,10 +3460,17 @@ class call {
3308
3460
  console.trace( e )
3309
3461
  }
3310
3462
 
3311
- if( true === this.#noack ) {
3312
- await this._onlatebridge()
3313
- } else {
3314
- await this._onearlybridge()
3463
+ try {
3464
+ if( true === this.#noack ) {
3465
+ await this._onlatebridge()
3466
+ } else {
3467
+ await this._onearlybridge()
3468
+ }
3469
+ } catch ( e ) {
3470
+ console.trace( e )
3471
+ if( this.destroyedcancelledorhungup ) {
3472
+ return
3473
+ }
3315
3474
  }
3316
3475
 
3317
3476
  try {
@@ -3635,6 +3794,11 @@ class call {
3635
3794
  newcall.#setdialog( newdialog )
3636
3795
  await newcall.#onnewuacsuccess( callbacks )
3637
3796
 
3797
+ if( newcall.destroyedcancelledorhungup ) {
3798
+ callstore.delete( newcall )
3799
+ if( callbacks.fail ) callbacks.fail( newcall )
3800
+ }
3801
+
3638
3802
  return newcall
3639
3803
  }
3640
3804
 
@@ -3649,6 +3813,11 @@ class call {
3649
3813
  if( this.destroyedcancelledorhungup ) return
3650
3814
 
3651
3815
  this._dialog = d
3816
+
3817
+ /* not established until we ack */
3818
+ this.state.establishing = true
3819
+ if( this.#noack ) return
3820
+
3652
3821
  this.established = true
3653
3822
  }
3654
3823
 
@@ -35,6 +35,7 @@ class callmanager {
35
35
  Parse invite maessages from drachtio.
36
36
  @private
37
37
  */
38
+ // eslint-disable-next-line complexity
38
39
  async _oninvite( req, res, next ) {
39
40
  if( "INVITE" !== req.msg.method ) return next()
40
41
 
@@ -59,15 +60,22 @@ class callmanager {
59
60
  try {
60
61
  await this.onnewcall( c )
61
62
  } catch( e ) {
62
- /* auth failed or timed out excluded as this is noral(ish) */
63
- if( 403 === e.code ) return
64
- if( 408 === e.code ) return
65
- if( true === e.normalandsilent ) return
66
-
67
- console.trace( e )
68
-
69
- if( c.destroyed ) return
70
- c.hangup( this.hangupcodes.SERVER_ERROR )
63
+ try{
64
+ /* auth failed or timed out excluded as this is noral(ish) */
65
+ if( "object" === typeof e ) {
66
+ if( 403 === e.code ) return
67
+ if( 408 === e.code ) return
68
+ if( true === e.normalandsilent ) return
69
+ }
70
+
71
+ console.trace( e )
72
+
73
+ if( c.destroyedcancelledorhungup ) return
74
+
75
+ c.hangup( this.hangupcodes.SERVER_ERROR )
76
+ } catch( e ) {
77
+ console.error( e )
78
+ }
71
79
  }
72
80
  }
73
81
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@babblevoice/babble-drachtio-callmanager",
3
- "version": "3.6.9",
3
+ "version": "3.6.10",
4
4
  "description": "Call processing to create a PBX",
5
5
  "main": "index.js",
6
6
  "scripts": {