question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Monitored event with a return type throws InvalidProgramException after invocation

See original GitHub issue

Description

If you create monitor for any type with an event that has a return type, and then invoke that event, it will throw InvalidProgramException. Issue reproduces on events with parameters and without it, with reference return type and with value return type. Looks like it’s happens because EventHandlerFactory.GenerateHandler() can’t create delegate with a return type. If you take a closer look, you can see that stack is empty when Ret instruction is called, I’m not sure about this, but look like it’s a reason of this issue. For testing i added ilGen.Emit(OpCodes.Ldc_I4_1); before Ret instruction and exception was not thrown, and event return True.

Complete minimal example reproducing the issue

public class Tests
{
    [Test]
    public void FollowingCausesError()
    {
        var target = new Subject();
        using (var monitor = target.Monitor())
        {
            target.Invoke();
        }
    }
}

class Subject
{
    public void Invoke()
    {
        Target?.Invoke();
    }

    public event Func<bool> Target;
}

Expected behavior:

Throw an exception on AssertionExtension.Monitor() invocation with message like “Can’t create monitor for event {eventName} because it has a return value” (and add a description for this to documentation).

Actual behavior:

Throws an InvalidProgramException after target.Invoke() with following message:

System.InvalidProgramException : Common Language Runtime detected an invalid program.
   at Func`2DynamicHandler(IEventRecorder , Int32 )
   at FailureDemo.Subject.Invoke(Int32 i) in C:\Users\uvaro\RiderProjects\FailureDemo\UnitTest1.cs:line 24
   at FailureDemo.Tests.FollowingCausesError() in C:\Users\uvaro\RiderProjects\FailureDemo\UnitTest1.cs:line 15

Versions

Reproduced on .NET Core 3.1 and .NET Framework 4.8 with Fluent Assertions v5.10.3

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
dennisdoomencommented, Nov 11, 2020

You misunderstood me. We’re not planning to support anything but the official Microsoft guideline. If you use an event, you’re supposed to use the EventArgs sub-class to share data with all the subscribers. But returning data from the subscriber back to the code that raises is it, is tricky at best. You have no control on how many subscribers you have. That’s why events have lost their popularity and people often switch to callback constructions like Action and Func.

1reaction
dennisdoomencommented, Nov 10, 2020

Well, the best we can do is to try to handle unexpected exceptions a bit better, but considering the complexity of the generation code, it’s going to be hard. Plus, it’s quite weird to use Func<bool> and event at the same time.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Developers - Monitored event with a return type throws ...
If you create monitor for any type with an event that has a return type, and then invoke that event, it will throw...
Read more >
c# - System.InvalidProgramException Common Language ...
Seeing this error message whilst trying to check the expression's correctness and if it is the correct IL. The expression is "DateTimeA.
Read more >
Bug - Invalid IL Code Exception with Ref Parameters and ...
It appears that when a delegate in Unity has a return type and more than four input parameters, a System.InvalidProgramException with the ...
Read more >
All .Net Exceptions List
The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the invoked...
Read more >
Complete List of Exception Class in C#
It is thrown when try to read or write protected memory. AggregateException, Represents one or more errors that occur during application execution.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found