ArxOne / MrAdvice

.NET aspect weaver (build task under NuGet package)
MIT License
311 stars 45 forks source link

Getting highest call hierarchy method #118

Closed hhblaze closed 7 years ago

hhblaze commented 7 years ago

Hi, such question. Simple try catch aspect. If method has unhandled exception, it must be logged and exception must be re-thrown to the caller of this method, but if there is no caller for the method (like function main, or method is a delegate, highest method in a call ierarchy) such exception must be logged by aspect and swallowed (not re-thrown). Is there a way to understand the place of the method in a call chain and build up smart aspects?

picrap commented 7 years ago

Hi,

did you take a look at StackTrace?

hhblaze commented 7 years ago

Yes, I do smth. like this right now, I thought may be we got integrated solution. I have finished with the code like this for now:

 public async Task Advise(MethodAsyncAdviceContext context)
        {

            try
            {                
                await context.ProceedAsync();
            }            
            catch (Exception ex)
            {
                StackTrace stackTrace = new StackTrace();
                var frames = stackTrace.GetFrames();                

                int c = 0;
                bool h = true;                
                for (int i = frames.Length - 1; i >= 0; i--)
                {   
                    if (frames[i].GetMethod().Name == "ProceedAspect")
                        c++;
                    if (c > 1)
                    {
                        h = false;
                        break;
                    }
                }

                if (h)
                {
                    Console.WriteLine("p1 highest level: " + ex.ToString());
                }
                else
                {
                    Console.WriteLine("p2: " + ex.ToString());
                    throw ex;
                }                
            }

        }

Thank you!

aliegeni commented 7 years ago
public class MyAspect : Attribute, IMethodAsyncAdvice
{
    public async Task Advise(MethodAsyncAdviceContext context)
    {
        try
        {
            await context.ProceedAsync();
        }
        catch (Exception ex)
        {
            var rethrow = new StackTrace().GetFrames()?.Any(f => f.GetMethod().Name == "ProceedAsync");
            if (rethrow.HasValue && rethrow.Value) throw;
            Console.WriteLine($"[{context.TargetType.Name}.{context.TargetMethod.Name}] {ex} -> MrAdvice catch!");
        }
    }
}