danbarua / NEventSocket

A reactive FreeSwitch eventsocket library for Modern .Net
Mozilla Public License 2.0
74 stars 37 forks source link

No FILE NOT FOUND exception? #39

Closed m-jepson closed 8 years ago

m-jepson commented 8 years ago

When I send a playback command to FreeSWITCH with a non-existing file as a parameter, I will see an error in the console (logging), but the task object has Exception = NULL after awaiting it and no exception is thrown. I think it should throw an exception when trying to playback a file that does not exist.

danbarua commented 8 years ago

Workaround: You can inspect the PlayResult object returned from a .Play() call to determine if it succeeded or not.

I did actually implement FileNotFound exceptions from .Play() a long time ago, along with exceptions thrown on dialplan application failures but I decided against it - my code was becoming cluttered with the indentation caused by lots of nested try{} catch{} blocks inside .Subscribe() callbacks. The top priority for this library is to allow me to write comms applications with clean code.

For now, NEventSocket only throws OperationCanceledExceptions to abort any awaited Tasks when the connection closes down, which keeps error handling simple.

I'm having a think about whether to expose a static config option, eg. EventSocket.ThrowOnApplicationFailure = true to make the proposed behaviour opt-in.

m-jepson commented 8 years ago

Channel.Play returns a simple Taskobject, not a Task<PlayResult> ? I'm using the latest Nuget release (v. 1.1.0)

danbarua commented 8 years ago

Ah. The Channel implementation is slightly different from the low-level one - if a Channel is bridged you need to do a displace_session rather than a play operation, and they return different results. Could you paste me a trace level log and I can see what we can do about returning something useful from this method.

m-jepson commented 8 years ago

The channel is not bridged, I just have an incoming channel caught using the OutboundListener.Channels.Subscribe method. I can just receive a new incoming Channel and then (after answering it) I do channel.Play(...) with a non-existent file and it just does not play anything. I can see errors in the log, just not in code. The returned object is a plain Task which seems to not have Faulted.

This is in the logs:

2016-06-09 13:40:25,528 [16] DEBUG NEventSocket.OutboundSocket (1) - Messages Received [text/event-plain].
2016-06-09 13:40:25,530 [16] DEBUG NEventSocket.OutboundSocket (1) - 5633daec-9fb6-45fd-8984-218357955bbe ChannelExecuteComplete [Answered answer _none_]
2016-06-09 13:40:25,958 [16] DEBUG NEventSocket.OutboundSocket (1) - Sending [sendmsg 5633daec-9fb6-45fd-8984-218357955bbe
Event-UUID: 521c3e84-b77b-4223-b37d-2fe876d6031f
call-command: execute
execute-app-name: playback
content-type: text/plain
content-length: 65

/usr/local/freeswitch/sounds/customers/2378/prompts/nl/Intros.wav
]
2016-06-09 13:40:25,962 [19] DEBUG NEventSocket.OutboundSocket (1) - Messages Received [command/reply].
2016-06-09 13:40:25,962 [19] DEBUG NEventSocket.OutboundSocket (1) - CommandReply received [+OK] for [sendmsg 5633daec-9fb6-45fd-8984-218357955bbe
Event-UUID: 521c3e84-b77b-4223-b37d-2fe876d6031f
call-command: execute
execute-app-name: playback
content-type: text/plain
content-length: 65

/usr/local/freeswitch/sounds/customers/2378/prompts/nl/Intros.wav
]
2016-06-09 13:40:25,982 [15] DEBUG NEventSocket.OutboundSocket (1) - Messages Received [text/event-plain].
2016-06-09 13:40:25,983 [15] DEBUG NEventSocket.OutboundSocket (1) - 5633daec-9fb6-45fd-8984-218357955bbe ChannelExecuteComplete [Answered playback FILE NOT FOUND]
2016-06-09 13:40:25,985 [15] ERROR NEventSocket.OutboundSocket - Application playback /usr/local/freeswitch/sounds/customers/2378/prompts/nl/Intros.wav failed - FILE NOT FOUND
danbarua commented 8 years ago

Yep cool, I can easily return the PlayResult from the underlying low-level .Play() call - which works in the case of a single-leg call. It looks like displace_session doesn't return any useful error responses however which is what we'd need in the case of a bridged channel. I'll go looking in the FreeSwitch source code to see what I can find.

m-jepson commented 8 years ago

It seems the PlayGetDigits method is having the same issue when I give it non-existant files as a PromptAudioFile or as a BadInputAudioFile.

danbarua commented 8 years ago

I've had a look at PlayGetDigits - if the PromptAudioFile is invalid it will attempt to play the BadInputAudioFile (upto MaxTries times) and then return a failure.

Unfortunately, there is nothing in the application response from FreeSwitch that we can use to determine why the application failed. :(

danbarua commented 8 years ago

Try the latest pre-release build: nuget install NEventSocket -PreRelease -Source "https://www.myget.org/F/neventsocket-prerelease/api/v3/index.json"

m-jepson commented 8 years ago

I am trying that version, but it won't do a play file at all now. No matter if the file exists or not, I get a KeyNotFoundException.

danbarua commented 8 years ago

Woops, I thought I'd fixed that. Have you got a stacktrace?

m-jepson commented 8 years ago

I already reverted to the 1.1.0 version for development reasons. Going to retry with 2.0 now.

m-jepson commented 8 years ago

Hmm, this is just weird. Now it works without any problems. Can't test anymore at the moment, as the FreeSWITCH servers need to be rebooted ... I'll keep you posted when I can get back on it.

m-jepson commented 8 years ago

It seems to be working okay now, I get the expected results for an existing file and a non-existing file. But now, after the call has been disconnected, I get the following error, which seems to come from the library itself:

2016-06-10 09:32:26,875 [16] FATAL CM.Voice.VoiceAPI.Service - Internal error: unhandled exception
System.NullReferenceException: Object reference not set to an instance of an object.
   at NEventSocket.Channels.Channel.<<InitializeSubscriptions>b__41>d__55.MoveNext() in c:\projects\neventsocket\src\NEventSocket\Channels\Channel.cs:line 372
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_1(Object state)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
danbarua commented 8 years ago

Just to confirm, is this with 2.0.0-build00208 ?

m-jepson commented 8 years ago

Yes, or at least, the latest version from nuget install NEventSocket -PreRelease -Source "https://www.myget.org/F/neventsocket-prerelease/api/v3/index.json"

danbarua commented 8 years ago

Can you try 2.0.0-build00209?

m-jepson commented 8 years ago

Seems to be working like a charm now. Thanks!

danbarua commented 8 years ago

@m-jepson happy to close this?

danbarua commented 8 years ago

Closing due to inactivity.