Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decorating "async void" method throws weaver exception for aspect with OnException override #111

Open
jowliwon opened this issue Nov 28, 2022 · 9 comments
Labels

Comments

@jowliwon
Copy link

jowliwon commented Nov 28, 2022

So, the thing is I have this injection script I run on all my source files so they can all be monitored and observed for issues.
It works well, instead of just do all of this manually.

I have these put on class level, not on individual methods like the example bellow.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TraceLog.Debugger.TestObjects
{
    [ExceptionLogger]
    public class MainAwait
    {
        public MainAwait()
        {
         
        }

        private async void GetAsync()
        {
            await WaitForResponse();
        }

        private async Task<bool> WaitForResponse()
        {
            await Task.Delay(1);
            return true;
        }
    }
}

How ever as Im only interested in capturing Exceptions at this stage, I have the ExceptionLogger it self look like this

using MethodBoundaryAspect.Fody.Attributes;
using TraceLog.AttributeHandlers;
using TraceLog.Configuration;
using System;
using System.Collections.Generic;
using System.Text;

namespace TraceLog
{
    public class ExceptionLoggerAttribute : OnMethodBoundaryAspect
    {
        private readonly ExecutionTypes executionTypes = ExecutionTypes.Instance;

        public override void OnException(MethodExecutionArgs arg)
        {
                executionTypes.OnEntryActivity(arg);
                executionTypes.OnExceptionActivity(arg);            
        }
    }
}

This how ever will cause the weaver to drop error message on by that not compile.

Severity	Code	Description	Project	File	Line	Suppression State
Error		Fody: An unhandled exception occurred:
Exception:
Failed to execute weaver D:\Repos\tracelogger\packages\MethodBoundaryAspect.Fody.2.0.148\build\..\weaver\MethodBoundaryAspect.Fody.dll
Type:
System.Exception
StackTrace:
   at InnerWeaver.ExecuteWeavers() in C:\projects\fody\FodyIsolated\InnerWeaver.cs:line 221
   at InnerWeaver.Execute() in C:\projects\fody\FodyIsolated\InnerWeaver.cs:line 111
Source:
FodyIsolated
TargetSite:
Void ExecuteWeavers()
Async state machine for System.Void TraceLog.Debugger.TestObjects.MainAwait::GetAsync() did not catch exceptions in the expected way.
Type:
System.InvalidOperationException
StackTrace:
   at MethodBoundaryAspect.Fody.AsyncMethodWeaver.WeaveOnException(IList`1 allAspects, Instruction instructionCallStart, Instruction instructionCallEnd, Instruction instructionAfterCall, IPersistable returnValue)
   at MethodBoundaryAspect.Fody.MethodWeaver.Weave()
   at MethodBoundaryAspect.Fody.ModuleWeaver.WeaveMethod(ModuleDefinition module, MethodDefinition method, List`1 aspectInfos, MethodInfoCompileTimeWeaver methodInfoCompileTimeWeaver)
   at MethodBoundaryAspect.Fody.ModuleWeaver.WeaveType(ModuleDefinition module, TypeDefinition type, Collection`1 assemblyMethodBoundaryAspects)
   at MethodBoundaryAspect.Fody.ModuleWeaver.WeaveTypeAndNestedTypes(ModuleDefinition module, TypeDefinition type, Collection`1 assemblyMethodBoundaryAspects)
   at MethodBoundaryAspect.Fody.ModuleWeaver.Execute(ModuleDefinition module)
   at MethodBoundaryAspect.Fody.ModuleWeaver.Execute()
   at InnerWeaver.ExecuteWeavers() in C:\projects\fody\FodyIsolated\InnerWeaver.cs:line 185
Source:
MethodBoundaryAspect.Fody
TargetSite:
Void WeaveOnException(System.Collections.Generic.IList`1[MethodBoundaryAspect.Fody.AspectData], Mono.Cecil.Cil.Instruction, Mono.Cecil.Cil.Instruction, Mono.Cecil.Cil.Instruction, MethodBoundaryAspect.Fody.IPersistable)	TraceLog.Debugger			

This only happens when dealing with OnException on class level, OnEntry and OnExit passes just fine.
Is there anything that can be done to deal with an issue like this?

@Ralf1108
Copy link
Collaborator

Does it compile if you provide empty overrides for OnEntry and OnExit methods?

@jowliwon
Copy link
Author

Im afraid not. As soon as OnException is in the code it stops compiling, with or without OnEntry and OnExit.

@Ralf1108
Copy link
Collaborator

Can you try to return a Task or an int from the GetAsync() method? Maybe there are problems with fire and forget async method weaving

@jowliwon
Copy link
Author

That worked!

        private async Task GetAsync()
        {
            await WaitForResponse();
        }
        private async Task<bool> WaitForResponse()
        {
            await Task.Delay(1);
            return true;
        }

@Ralf1108
Copy link
Collaborator

Ralf1108 commented Nov 28, 2022

Great. Then this should also be reproducible if the attribute is just decorating the GetAsync() method if it returns void?

@jowliwon
Copy link
Author

Yes, by having this on method level, its the same behavior. With and with out returning Task.

@Ralf1108
Copy link
Collaborator

So then the bug is handling of void async methods.
Wondering why this was not detected earlier.

So all in all you have a workaround and we can then create a test case for the issue

@Ralf1108 Ralf1108 added the bug label Nov 28, 2022
@Ralf1108 Ralf1108 changed the title OnException on class level dose not work together with await & asyc Decorating "async void" method throws weaver exception for aspect with OnException override Nov 28, 2022
@elmondir
Copy link

any workaround for this issue?

@jowliwon
Copy link
Author

any workaround for this issue?

Sort of. Have to return a task, just read above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants