Csla.Xaml.InvokeMethod exception handling

Csla.Xaml.InvokeMethod exception handling

Old forum URL: forums.lhotka.net/forums/t/10738.aspx


BrianPerry posted on Wednesday, October 05, 2011

This is the scenario:

The problem is that InvokeMethod.CallMethod has a catch block that rethrows exceptions thrown by view model code, which resets the exception call stack. The result is uninformative logged exceptions like the one below.

System.NullReferenceException: Object reference not set to an instance of an object.
   at Csla.Xaml.InvokeMethod.CallMethod(Object sender, EventArgs e) 
   at blah blah blah

One solution is to simply eliminate the try-catch in InvokeMethod.CallMethod. Do I lose anything essential by doing that? Is there a better solution?

 

RockfordLhotka replied on Wednesday, October 05, 2011

InvokeMethod is deprecated and will be removed in a future version.

You should consider using TriggerAction instead. It is more flexible, more powerful, and provides better debugging overall.

BrianPerry replied on Wednesday, October 05, 2011

Switching to TriggerAction may be a good idea for other reasons, but it has the same try-catch logic as InvokeMethod, with the same effect on the exception call stack.

System.NullReferenceException: Object reference not set to an instance of an object.
   at Csla.Xaml.TriggerAction.CallMethod(Object sender, EventArgs e)

So to rephrase the question, what, if anything, do I lose by eliminating the try-catch from TriggerAction.CallMethod, and letting the original exception, with its original call stack, flow naturally up to the global exception handler as the inner exception to the TargetInvocationException? The resulting log entry is longer as a result, but unlike the above entry it provides useful information.

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at ViewModels.ViewModel.Calculate() in etc.
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
   at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Csla.Xaml.TriggerAction.CallMethod(Object sender, EventArgs e)

RockfordLhotka replied on Thursday, October 06, 2011

I don't know that there's any real drawback to what you propose.

The reason we swallow TargetInvocationException is that it is the only exception that really occurs, and it obscures the underlying inner exception (the one you really care about). So we were trying to be helpful :)

 

BrianPerry replied on Thursday, October 06, 2011

Helpful is good. Unfortunately, System.Exception offers two less than ideal options: expose the irrelevant exception or lose the stack trace. The following link suggests that there might be a better option in the future.

https://connect.microsoft.com/VisualStudio/feedback/details/633822/allow-preserving-stack-traces-when-rethrowing-exceptions

Copyright (c) Marimer LLC