ReactiveUI's ReactiveCommand Exception handling - c#

I'm trying to handle Exception thrown inside ReactiveUI (7.4.0.0)'s commands, but everything seems to be swllowed somehwere inside and never comes out but in Visual Studio's Output window.
My test code is this:
class Program
{
static void Main(string[] args)
{
try
{
var ata = ReactiveCommand.CreateFromTask(async () => await AsyncTaskThrowException());
ata.ThrownExceptions.Subscribe(ex => Console.WriteLine($"async with await:\t{ex.Message}"));
ata.Execute();
// Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
// Exception thrown: 'System.Exception' in Test.exe
// Exception thrown: 'System.Exception' in mscorlib.dll
var atna = ReactiveCommand.CreateFromTask(() => AsyncTaskThrowException(),null, RxApp.MainThreadScheduler);
atna.ThrownExceptions.Subscribe(ex => Console.WriteLine($"async without await:\t{ex.Message}"));
atna.Execute();
// Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
// Exception thrown: 'System.Exception' in Test.exe
var ta = ReactiveCommand.CreateFromTask(async () => await TaskThrowException());
ta.ThrownExceptions.Subscribe(ex => Console.WriteLine($"async without await:\t{ex.Message}"));
ta.Execute();
// Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
// Exception thrown: 'System.Exception' in Test.exe
var tna = ReactiveCommand.CreateFromTask(() => TaskThrowException());
tna.ThrownExceptions.Subscribe(ex => Console.WriteLine($"async without await:\t{ex.Message}"));
tna.Execute();
// Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
// Exception thrown: 'System.Exception' in Test.exe
// Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
var sf = ReactiveCommand.Create(() => ThrowException());
sf.ThrownExceptions.Subscribe(ex => Console.WriteLine($"sync:\t{ex.Message}"));
sf.Execute();
// Exception thrown: 'System.InvalidOperationException' in System.Reactive.Windows.Threading.dll
}
catch (Exception ex)
{
Debug.WriteLine($"{nameof(ex.Message)}: {ex.Message}");
Debug.WriteLine($"{nameof(ex.StackTrace)}: {ex.StackTrace}");
}
Console.ReadLine();
}
static async Task<string> AsyncTaskThrowException()
{
await Task.Delay(100);
throw new Exception("Exception in async Task");
}
static Task<string> TaskThrowException()
{
throw new Exception("Exception in non-async Task");
}
static string ThrowException()
{
throw new Exception("Exception in sync func");
}
}
Under each call there are the Exception's thrown if I comment everything but that .Execute() call (intentional one included).
The only call that prints something is the third:
ReactiveCommand.CreateFromTask(() => TaskThrowException());
But still throws something.
Can you help me understand why the other Exceptions don't get piped into ThrownExceptions, and how to completely handle errors so they don't get logged in the Output window?
Thanks!

Related

'System.NotImplementedException' occurred in mscorlib.dll

does anyone know how to fix this exception?
An unhandled exception of type 'System.NotImplementedException' occurred in mscorlib.dll
I'm using .NET microframework 4.1 and I have the "mscorlib" reference added but when I try to load a BMP image from the resources:
internal static Microsoft.SPOT.Bitmap GetBitmap(Resources.BitmapResources id)
{
return Microsoft.SPOT.Bitmap(Microsoft.SPOT.ResourceUtility.GetObject(ResourceManager, id));
}
[System.SerializableAttribute()]
internal enum BitmapResources : short
{
image = 24837,
}
I get that exception in the return sentence.
Stack trace:
System.Resources.ResourceManager::GetObjectInternal\r\nS‌​ystem.Resources.Reso‌​urceManager::GetObje‌​ctFromId\r\nMicrosof‌​t.SPOT.ResourceUtili‌​ty::GetObject\r\nFEZ‌​TouchDriver_Example.‌​Resources::GetBitmap‌​\r\nFEZTouchDriver_E‌​xample.Program::Init‌​Graphics\r\nFEZTouch‌​Driver_Example.Progr‌​am::Main\r\n" string

unhandled exceptions at startup in my c# project

I am getting below Unhandled exception at the startup of my chatbot application in output window.
Exception thrown: 'System.UnauthorizedAccessException' in mscorlib.dll
Exception thrown: 'System.Globalization.CultureNotFoundException' in mscorlib.dll
Exception thrown: 'System.Security.SecurityException' in mscorlib.dll
Exception thrown: 'System.BadImageFormatException' in mscorlib.dll
Exception thrown: 'System.ArgumentNullException' in mscorlib.dll
Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll
Exception thrown: 'System.IO.FileNotFoundException' in mscorlib.dll
I have something in my MessageController
public class MessagesController : ApiController
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private static DocumentClient client;
// Retrieve the desired database id (name) from the configuration file
private static readonly string databaseId = ConfigurationManager.AppSettings["DatabaseId"];
// Retrieve the desired collection id (name) from the configuration file
private static readonly string collectionId = ConfigurationManager.AppSettings["CollectionId"];
// Retrieve the DocumentDB URI from the configuration file
private static readonly string endpointUrl = ConfigurationManager.AppSettings["EndpointUri"];
// Retrieve the DocumentDB Authorization Key from the configuration file
private static readonly string authorizationKey = ConfigurationManager.AppSettings["PrimaryKey"];
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
Trace.TraceInformation($"Type={activity.Type} Text={activity.Text}");
//disable the Application Insights and DocumentDb logging in local enviornment
#if (LOCAL)
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.DisableTelemetry = true;
#endif
#if (!LOCAL)
if (!String.IsNullOrEmpty(endpointUrl) && !String.IsNullOrEmpty(authorizationKey))
{
using (client = new DocumentClient(new Uri(endpointUrl), authorizationKey))
{
await CaptureConversationData(activity);
}
}
#endif
if (activity.Type == ActivityTypes.Message)
{
//await Microsoft.Bot.Builder.Dialogs.Conversation.SendAsync(activity, () => new ContactOneDialog());
//Implementation of typing indication
//ConnectorClient connector = new ConnectorClient(new System.Uri(activity.ServiceUrl));
//Activity isTypingReply = activity.CreateReply("Shuttlebot is typing...");
//isTypingReply.Type = ActivityTypes.Typing;
//await connector.Conversations.ReplyToActivityAsync(isTypingReply);
logger.Debug("The User's local timeStamp is: " + activity.LocalTimestamp + "and service timeStamp is: " + activity.Timestamp);
await Conversation.SendAsync(activity, () =>
new ExceptionHandlerDialog<object>(new ShuttleBusDialog(), displayException: true));
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(System.Net.HttpStatusCode.OK);
return response;
}
}
It thrown at first line
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
here is the snapshot,
One weired thing is that if my project run from C:\Users\\chatbot\Mybot..
then these exception are not getting thrown even i have put the break exception setting in exception setting window.
but if I move the project to c:\Sandy\MyStuff\ChatbOt\MyBot it's started throwing all these exception since i have put the break exception setting in exception setting window.
I am seriously not able to understand what is the problem.
Try running your visual studio as administrator or running your application as administrator, and check that all the Dlls that your project depends on are there in the new path.

Unobserved exception was rethrown despite awaiting the Task and catching Exception

I have code that catches all exceptions that are thrown by a server call as follows:
new public Task SaveAsync()
{
return ServerException.Wrap(base.SaveAsync);
}
Where ServerException.Wrap looks like:
public static async Task<T> Wrap<T>(Func<Task<T>> func)
{
try
{
return await func();
}
catch (Exception ex)
{
// This is an internal error that shouldn't happen.
throw new ServerException(ex);
}
}
public static async Task Wrap(Func<Task> func)
{
await Wrap(async () =>
{
await func();
return true;
});
}
And then I have a function that calls SaveAsync as follows:
try
{
await problem.SaveAsync();
}
catch (ServerException ex)
{
Logger.LogException("Error saving problem.", ex);
}
I have some internal error that generates an exception which I catch in the above line and then it gets logged as follows:
2015-10-20 11:20:44.502 [Line 99] Error saving problem. (Exception:
Exceptions.ServerException: ---> System.ArgumentException: An item
with the same key has already been added. at
System.ThrowHelper.ThrowArgumentException (ExceptionResource resource)
[0x00000] in
/Users/builder/data/lanes/1977/2c66d2fe/source/mono/external/referencesource/mscorlib/system/throwhelper.cs:74
However a few seconds later I get an unhanded exception warning that gets logged:
2015-10-20 11:21:16.352 Warning: Unhandled exception:
System.AggregateException: A Task's exception(s) were not observed
either by Waiting on the Task or accessing its Exception property. As
a result, the unobserved exception was rethrown by the finalizer
thread. ---> System.ArgumentException: An item with the same key has
already been added. at System.ThrowHelper.ThrowArgumentException
(ExceptionResource resource) [0x00000] in
/Users/builder/data/lanes/1977/2c66d2fe/source/mono/external/referencesource/mscorlib/system/throwhelper.cs:74
Why do I get the second unobserved exception, even though I am catching and handling the first exception? This exception seems to be thrown by my ServerException.Wrap method.
I am using MonoTouch.
You need to explicitly set the exception to observed.
For that, you need to subscribe to the TaskScheduler's UnobservedTaskException event, and set it explicitly to observed (call SetObserved() on it).
See here:
UnobservedTaskException being throw...
EDIT:
Of course, you can also just catch AggregateException as well, or use ContinueWith() to observe and resume the task.
See the bottom of the official documentation:
Exception Handling (MSDN)

Async/await exception and Visual Studio 2013 debug output behavior

I'm developing an application in C# that communicates with Dynamics NAV through web services. To reduce duplicate code and because there will be many endpoints, I have created a generic async/await method that executes the service calls and handle exceptions.
The method works but I'm seeing an unexpected behavior in the Visual Studio 2013 output window when an exception occur(and is handled).
Test code and output can be seen below.
My concern is the "A first chance exception of type..." lines which I'm seeing 4 times when using the async/await methods. Does this exception really occur 4 times?
When calling the service synchronously there's only one exception line which is expected.
Is this just Visual Studio 2013 or is there something wrong with my async/await code?
Is there maybe a better way of doing what I'm trying to accomplish?
class Program
{
static void Main(string[] args)
{
Debug.WriteLine("Synchronous...");
try
{
TestFunctions_PortClient service = new TestFunctions_PortClient();
service.Open();
string result = service.ErrorTest();
Debug.WriteLine(result);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
Debug.WriteLine(string.Empty);
Debug.WriteLine("Async...");
NavServiceTest navService = new NavServiceTest();
navService.TestAsync();
Console.ReadLine();
}
}
class NavServiceTest
{
public async void TestAsync()
{
try
{
string result = await CallServiceAsync();
Debug.WriteLine(result);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private async Task<string> CallServiceAsync()
{
TestFunctions_PortClient service = new TestFunctions_PortClient();
service.Open();
ErrorTest_Result result = await ExecuteServiceAsync<ErrorTest_Result>(
service.InnerChannel,
service.Endpoint,
service.ErrorTestAsync());
return result.return_value;
}
private async Task<T> ExecuteServiceAsync<T>(IClientChannel channel, ServiceEndpoint endpoint, Task<T> source)
{
var tcs = new TaskCompletionSource<T>();
Task<T> task = tcs.Task;
try
{
Debug.WriteLine("ExecuteServiceAsync");
tcs.TrySetResult(await source);
}
catch (EndpointNotFoundException ex)
{
Debug.WriteLine("EndpointNotFoundException");
tcs.TrySetException(ex);
}
catch (FaultException ex)
{
Debug.WriteLine("FaultException");
tcs.TrySetException(ex);
}
catch (Exception ex)
{
Debug.WriteLine("Exception");
tcs.TrySetException(ex);
}
finally
{
if (channel != null)
{
if (channel.State == CommunicationState.Faulted)
channel.Abort();
else
channel.Close();
}
}
if (task.IsFaulted)
{
throw task.Exception.InnerException;
}
return task.Result;
}
}
Here's the output of the code above.
Synchronous...
A first chance exception of type 'System.ServiceModel.FaultException' occurred in mscorlib.dll
Error from NAV
Async...
ExecuteServiceAsync
A first chance exception of type 'System.ServiceModel.FaultException' occurred in mscorlib.dll
FaultException
A first chance exception of type 'System.ServiceModel.FaultException' occurred in ServiceTest.exe
A first chance exception of type 'System.ServiceModel.FaultException' occurred in mscorlib.dll
A first chance exception of type 'System.ServiceModel.FaultException' occurred in mscorlib.dll
Error from NAV
When an exception occurs in an async method, it doesn't just propagate up the stack like it does in synchronous code. Heck, the logical stack is likely not to be there any more.
Instead, the exception is stored in the task which represents the asynchronous operation. Then, when you await the asynchronous operation, the GetResult method of the TaskAwaiter will rethrow the original exception. If that isn't caught in your code, then it will be caught by the compiler-generated code again and put into the task that represents that operation, etc. So if you have a chain of asynchronous methods (as is often the case) and the deepest one throws an exception, the exception propagation will actually be a "throw in GetResult, catch, stuff into task" per link in the chain.
So yes, the exception is being thrown four times, in order to effectively only be thrown once. If you're worried about the efficiency of that, I suspect it's not too bad - because the logical stack trace is only determined once. I dare say it's less efficient than the synchronous version, but my general philosophy is that if you're seeing so many exceptions that they're affecting your performance significantly, then either you're overusing exceptions or your system is in a really bad state anyway, and performance is the least of your worries.

Not catching exception thrown by TaskEx.Run's task

I'm having trouble with the async CTP, trying to figure out what the correct way to handle exceptions is. The code below crashes my program, when as far as I can tell, the await should be catching and rethrowing the exception in the context it is called from, so the Not caught! block should catch the exception.
try {
await TaskEx.Run(() => {
throw new Exception();
});
} catch {
// Not caught!
}
Thanks for any help or suggestions.
Works fine for me using the beta (rather than the CTP, hence the TaskEx becoming Task):
using System;
using System.Threading.Tasks;
class Test
{
static void Main()
{
Task t = Foo();
t.Wait();
}
static async Task Foo()
{
try
{
await Task.Run(() => { throw new Exception(); });
}
catch (Exception e)
{
Console.WriteLine("Bang! " + e);
}
}
Output:
Bang! System.Exception: Exception of type 'System.Exception' was thrown.
at Test.<Foo>b__0()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter
.HandleNonSuccessAndDebuggerNotification(Task task)
at Test.<Foo>d__2.MoveNext()
What does the same code do on your machine?
Pro Tip: Visual Studio is telling you that the exception is unhandled, but if you F5 through, you will see that it does get caught.
(This from comments on Jon's answer, but I think it deserves its own answer)
A little bit of rearranging should work:
await TaskEx.Run(() => {
try {
throw new Exception();
} catch {
// Caught!
}
});
EDIT:
I get the same results as Jon Skeet due to the fact that I'm also running the VS11 beta. I cannot speak for the CTP.

Categories

Resources