0

I have written Azure function v1 using C# (library project) with Aspect (AOP) for Logging. I'm not getting exception in catch block.

Catch an exception thrown by an async method

I have same problem discussed above, however, Azure Function Run method is Async Task and its exception handling same as async void. Not sure where is a problem? assuming this is function SDK issue.

Azure Function

public static class PingFunction
{
    [LoggerAspect]
    [FunctionName("PingFunction")]
    public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
    {
        string name = string.Empty;
        log.Info("C# HTTP trigger function processed a request.");

            SomeService someService = new SomeService();
            await someService.DoSomething();

        return req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
    }
}

public class SomeService
{
    public async Task DoSomething()
    {
        await Task.Delay(1000);
        throw new Exception("Exception from Service");
    }
}

Logger Aspect (MrAdvise)

public class LoggerAspectAttribute : Attribute, IMethodAdvice
{
    public void Advise(MethodAdviceContext context)
    {
        //Logger initilizer here
        Console.WriteLine($"{context.TargetType.Name} started...");
        try
        {
            context.Proceed(); // this calls the original method
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            Console.WriteLine($"{context.TargetType.Name} completed...");
        }
    }
}

Workaround When I removed Async-await from Azure function and call async method by "GetAwaiter().GetResult()", then it works.

public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
    {
        string name = string.Empty;
        log.Info("C# HTTP trigger function processed a request.");

        SomeService someService = new SomeService();
        someService.DoSomething().GetAwaiter().GetResult();

        return req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
    }

Task.GetAwaiter().GetResult() methods cause the potential for deadlock issues and should be avoided in favor of async/await.

My function process millions for events per-day. Is it the right solution if this is FunctionSDK issue or something else?

jazb
  • 5,498
  • 6
  • 37
  • 44
Pankaj Rawat
  • 4,037
  • 6
  • 41
  • 73
  • 2
    This is mostly to do with MrAdvice AOP framework support for Async calls, try using Postsharp, that would work as expected. `GetAwaiter().GetResult()` is not a good solution as that is making calls Synchronous – Mrinal Kamboj Jan 08 '19 at 07:34
  • 1
    If you are only keen for the free version, then please try https://github.com/Virtuoze/NConcern – Mrinal Kamboj Jan 08 '19 at 07:39
  • It's MrAdvice with a C :) – picrap Jan 09 '19 at 10:21

1 Answers1

0

you need to write an async advice, such as:

public class LoggerAspectAttribute : Attribute, IMethodAsyncAdvice
{
    public async Task Advise(MethodAsyncAdviceContext context)
    {
        //Logger initilizer here
        Console.WriteLine($"{context.TargetType.Name} started...");
        try
        {
            await context.ProceedAsync(); // this calls the original method
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            Console.WriteLine($"{context.TargetType.Name} completed...");
        }
    }
}

EDIT : and yes, it works with Mr Advice :)

picrap
  • 1,236
  • 1
  • 13
  • 35