How to convert an exception to another one using PostSharp? - c#

I would like to automagically add the following code around the body of some methods:
try
{
// method body
}
catch (Exception e)
{
throw new MyException("Some appropriate message", e);
}
I am working with PostSharp 1.0 and this is what I've done at the moment:
public override void OnException(MethodExecutionEventArgs eventArgs)
{
throw new MyException("Some appropriate message", eventArgs.Exception);
}
My problem is that I can see the PostSharp OnException call in the stack.
What would be the good practice to avoid this and get the same call stack as implementing by hand the exception handler?

There is no way to hide "OnException" from the call stack.

Two things working in tandem will allow you to do this:
The fact that Exception.StackTrace is virtual
The use of the skipFrames parameter to the StackFrame constructor. This is not required, but makes things easier
The below example demonstrates how to customize the stack trace. Note that I know of no way to customize the Exception.TargetSite property, which still gives the details of the method from which the exception originated.
using System;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// exception is reported at method A, even though it is thrown by method B
MethodA();
}
private static void MethodA()
{
MethodB();
}
private static void MethodB()
{
throw new MyException();
}
}
public class MyException : Exception
{
private readonly string _stackTrace;
public MyException()
{
// skip the top two frames, which would be this constructor and whoever called us
_stackTrace = new StackTrace(2).ToString();
}
public override string StackTrace
{
get { return _stackTrace; }
}
}
}

Related

Getting property name from within property type

I couldn't figure out how to formulate the title any better. I see quite a few posts with similar titles but which discuss entirely different stuff.
So here we go. The actual on-ground situation is complex, but I'll try to post an absolute minimalistic example to describe it.
Let's say we have a class named Animal:
class Animal
{
public void Run()
{
try
{
//try running
}
catch(Exception e)
{
MessageBox.Show(this.SomeCleverWayOfGettingPropertyName() + " failed to run");
}
}
}
Now I define several properties of Animal type in another class:
class Zoo
{
public Animal Zebra {get; set;}
public Animal Lion {get; set;}
public Animal Rhino {get; set;}
public void RunAll()
{
Zebra.Run();
Lion.Run();
Rhino.Run();
}
}
What do I write in place of SomeCleverWayOfGettingPropertyName() to let it show name of the animal (that is name of the declared property), like "Zebra failed to run".
As I said, the actual situation is more complex, so kindly avoid answers like, "why don't you redesign your entire code base and instead try X". My hope is to find something in System.Reflection to find out the calling member's name, but I haven't found anything like that yet.
Ideally you would rethink your problem, and possibly catch outside of the run
Depending on your exact needs, an expression might work.. However it really is a terrible solution, if you went to all the effort you might as well catch outside, or just pass the member name in.
Given
public class Animal
{
public void Run()
{
Console.WriteLine("Running");
}
}
public static class MemberInfoGetting
{
public static void Run<T>(this Expression<Func<T>> memberExpression) where T : Animal
{
var expressionBody = (MemberExpression)memberExpression.Body;
try
{
var animal = Expression.Lambda<Func<Animal>>(expressionBody).Compile()();
animal.Run();
throw new Exception("bob");
}
catch
{
Console.WriteLine($"{expressionBody.Member.Name} : failed to run");
}
}
}
Usage
public static Animal Rhino { get; set; } = new Animal();
public static void Main()
{
MemberInfoGetting.Run(() => Rhino);
}
Output
Running
Rhino : failed to run
This is basically not possible with this approach. What happens when you call Zebra.Run():
Runtime calls the auto-generated get_Zebra() method, putting the Zebra's Animal instance pointer on the stack.
Runtime calls the Animal.Run() instance method.
All variable/property info about where that instance came from is pretty much gone at that point.
Now Animal.Run() doesn't know it's being called on an instance that came from a property, and there's no guarantee it will be. It could as well be a local, a method parameter or a new()ed instance, one from a factory or a collection element. You'll have to pass this info yourself.
Alternatively, if it's for error handling, it may be easier than you think without having to resolve to compiler magic or expensive expression refactoring:
In your exception handler, log the relevant properties that identify the Animal instance. Combined with the stack trace, this should give you enough information.
you can try this:
class Animal
{
public void Run([CallerMemberName] string caller = null)
{
try
{
//try running
}
catch(Exception e)
{
MessageBox.Show(caller + " failed to run");
}
}
}
The only way to reasonable do this is change RunAll() such that it monitors each call, to the now modified run
class Animal
{
static readonly Random rng = new Random();
public bool Run()
{
if (rng.NextDouble() < 0.5)
{
return false;
}
return true;
}
}
class Zoo
{
...
public void RunAll()
{
try
{
if (!Zebra.Run())
{
throw new Exception(nameof(Zebra));
}
if (!Lion.Run())
{
throw new Exception(nameof(Lion));
}
if (!Rhino.Run())
{
throw new Exception(nameof(Rhino));
}
}
catch (Exception ex)
{
Debug.WriteLine($"{ex.Message} failed to run.");
}
}
}

Design pattern for surrounding code in start, complete and fail methods

Suppose I have various arbitrary sections of code to run, but before each section, I have to run a Start() method and then after each section I need to run a Complete() method. However, if an exception is thrown in the code section, I want to run a Fail(string message) method instead of Complete(). Is there a design pattern that elegantly encapsulates this to make it neat and easily repeatable?
For example, let's say I have a type called Thing that contains a Start() method that adds a row to a logging db table to reflect that a task is in progress, a Complete() method that changes that row to reflect that the task finished and a Fail(string message) method that changes the row to reflect that the task failed. These are just examples though, they could be doing any set-up and tidy up type tasks.
The naive implementation might be simply to call those methods manually:
public void DoStuff()
{
var thing = new Thing();
thing.Start();
try
{
DoImportantStuff();
thing.Complete();
}
catch (Exception e)
{
thing.Fail(e.Message);
}
}
But if I'm going to have to repeat this in a lot of different places, it ends up creating quite a lot of duplication and it might be easy to forget to call Complete or mess this up in some subtle way.
In C#, there's the using pattern, which provides a good way of encapsulating most of this. For example, if my Thing type looked like this:
public class Thing : IDisposable
{
public Thing(){
Start();
}
private void Start() { /* start */ }
private void Complete() { /* complete */ }
public void Dispose()
{
Complete();
}
}
My DoStuff() method could now be simplified to this:
public void DoStuff()
{
using(new Thing())
{
DoImportantStuff();
}
}
Which is much nicer. But it doesn't allow me to call Fail instead of Complete if an exception is thrown because (I think!) the Dispose method is essentially called in a Finally block.
I have thought of having a try/catch inside the using block and then setting a thing.HasFailed flag inside the catch block and then using that in the Dispose method to decide whether to Complete or Fail. But that seems a bit fiddly and I'd like the consumer of Thing to have to do as little as possible to make it work correctly.
So is there a design pattern that encapsulates what I want to do and avoids the need to manually write a try\catch each time?
You could have a Thing like this:
public class Thing
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string message) {}
public void DoAction(Action action)
{
this.Start();
try
{
action();
this.Complete();
}
catch (Exception e)
{
this.Fail(e.Message);
}
}
}
And Use it like this:
Thing thing = new Thing();
thing.DoAction(this.DoStuff);
The pattern is called "template method". You can find your implementation under the title "aspect oriented programming".
(https://msdn.microsoft.com/en-us/library/aa288717(v=vs.71).aspx)
Using Delegates.
public class Thing : IDisposable
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string _szMessage) {/* fail */}
public delegate void ProcessClientStuff();
private ProcessClientStuff m_delegateClientStuff;
public Thing(ProcessClientStuff _delegateClientStuff) {m_delegateClientStuff = _delegateClientStuff}
public void Dostuff()
{
Start();
try
{
m_delegateClientStuff();
Complete();
}
catch(Exception e)
{
Fail(e.Message);
}
}
}
void ClientStuff()
{
Console.WriteLine("Hello");
}
Thing oClientStuffProcessor = new Thing(ClientStuff);
oClientStuffProcessor.Dostuff();

handle exceptions with attributes

Can please someone explain, in a very easy/simple way, how to handle an exception via attributes?
For example if I have simple code like this:
class Test{
static void Main(string[] args){
try {
Console.WriteLine("div= "+ Division(0));
}
catch (DivideByZeroException e)
{
Console.WriteLine("Attempted divide by zero -->" + e.Message);
}
Console.ReadLine();
}
public static int Division(int i){ return 10 / i; }
}
How can I change this code using attributes?
This cannot be done with .NET out of the box.
tl;dr - There is no "very easy/simple way (...) to handle an exception via attributes"
You're trying to handle exceptions in a AOP way (aspect oriented programming), where you attach aspects to methods - using attributes, for example.
PostSharp allows you to do this:
Without postsharp:
public class OrderFulfillmentService
{
public void Fulfill( Order order )
{
try
{
// Do stuff.
}
catch ( Exception e )
{
if ( ExceptionHandler.Handle(e) )
throw;
}
}
}
With postsharp:
public class OrderFulfillmentService
{
[HandleException]
public void Fulfill( Order order )
{
// Do stuff.
}
}
Beware of the downsides of using AOP though: the code might become less readable (as it isn't written sequentially) and less maintainable.
Instead of using attributes, you could also use Castle Interceptor/DynamicProxy
You will need to create an interceptor that wraps around your object and intercepts calls to it. At runtime, Castle will make this interceptor either extend your concrete class or implement a common interface - this means you'll be able to inject the interceptor into any piece of code that targets the intercepted class. Your code would look something like this:
public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
try{
invocation.Proceed();
} catch(Exception ex) {
//add your "post execution" calls on the invocation's target
}
}
}
Introduction to AOP with Castle: http://docs.castleproject.org/Windsor.Introduction-to-AOP-With-Castle.ashx

TargetInvocationException in NSubstitute

I want to write a test checking, whether my abstract classes constructor correctly handles invalid arguments. I wrote a test:
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void MyClassCtorTest()
{
var dummy = Substitute.For<MyClass>("invalid-parameter");
}
This test does not pass, because NSubstitute throws a TargetInvocationException instead of ArgumentException. The actual exception I seek for is actually an InnerException of that TargetInvocationException. I can write a helper method like:
internal static class Util {
public static void UnpackException(Action a) {
try {
a();
} catch (TargetInvocationException e) {
throw e.InnerException;
} catch (Exception) {
throw new InvalidOperationException("Invalid exception was thrown!");
}
}
}
But I guess, that there rather should be some kind of general way of solving that problem. Is there one?
NSubstitute does not currently have a general way of solving this.
Some other workarounds include manually subclassing the abstract class to test the constructor, or manually asserting on the inner exception rather than using ExpectedException.
For example, say we have an abstract class that requires a non-negative integer:
public abstract class MyClass {
protected MyClass(int i) {
if (i < 0) {
throw new ArgumentOutOfRangeException("i", "Must be >= 0");
}
}
// ... other members ...
}
We can create a subclass in a test fixture to test the base class constructor:
[TestFixture]
public class SampleFixture {
private class TestMyClass : MyClass {
public TestMyClass(int i) : base(i) { }
// ... stub/no-op implementations of any abstract members ...
}
[Test]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestInvalidConstructorArgUsingSubclass()
{
new TestMyClass(-5);
}
// Aside: I think `Assert.Throws` is preferred over `ExpectedException` now.
// See http://stackoverflow.com/a/15043731/906
}
Alternatively you can still use a mocking framework and assert on the inner exception. I think this is less preferable to the previous option as it is not obvious why we're digging in to the TargetInvocationException, but here's an example anyway:
[Test]
public void TestInvalidConstructorArg()
{
var ex = Assert.Throws<TargetInvocationException>(() => Substitute.For<MyClass>(-5));
Assert.That(ex.InnerException, Is.TypeOf(typeof(ArgumentOutOfRangeException)));
}

Handle base class exception

I have a following C# scenario-
I have to handle an exception in base class that actually occurs in the derived class.
My base class looks like this:
public interface A
{
void RunA();
}
public class Base
{
public static void RunBase(A a)
{
try
{
a.RunA();
}
catch { }
}
}
The derived class is as follows:
public class B: A
{
public void RunA()
{
try
{
//statement: exception may occur here
}
catch{}
}
}
I want to handle the exception, lets say exception C, that occurs in B(at //statement above).
The exception handling part should be written in base class catch inside RunBase. How can this be done?
public class Base
{
public static void RunBase(A a)
{
try
{
a.RunA();
}
catch(SomeSpecialTypeOfException ex)
{
// Do exception handling here
}
}
}
public class B: A
{
public void RunA()
{
//statement: exception may occur here
...
// Don't use a try-catch block here. The exception
// will automatically "bubble up" to RunBase (or any other
// method that is calling RunA).
}
}
How can this be done?
What do you mean? Just remove the try-catch block from RunA.
Having said that, you need to make sure Class A knows how to handle the exception, this includes streamlining it to UI, logging, ... This is in fact rare for a base class. Handling exception normally happen at the UI level.
public class B: A
{
public void RunA()
{
try
{
// statement: exception may occur here
}
catch(Exception ex)
{
// Do whatever you want to do here if you have to do specific stuff
// when an exception occurs here
...
// Then rethrow it with additional info : it will be processed by the Base class
throw new ApplicationException("My info", ex);
}
}
}
You also might want to throw the exception as it is (use throw alone).
If you dont need to process anything here, dont put try{} catch{}, let the exception bubble up by itself and be processed by the Base class.
Just remove the try catch from class B, if the exception occurs it will propergate up the call chain until it is handled. In this case you can handle the exception in RunBase using your existing try catch block.
Though in your example B isn't derived from your base class Base. If you really want to handle a situation where an exception is thrown in a derived class in its parent you could try something like:
public class A
{
//Public version used by calling code.
public void SomeMethod()
{
try
{
protectedMethod();
}
catch (SomeException exc)
{
//handle the exception.
}
}
//Derived classes can override this version, any exception thrown can be handled in SomeMethod.
protected virtual void protectedMethod()
{
}
}
public class B : A
{
protected override void protectedMethod()
{
//Throw your exception here.
}
}

Categories

Resources