I am using NATS mechanism to publish events between different processes, when I subscribe to a topic and supply async action that handles the topic if an exception has been thrown from the action that handles the topic I can't catch it because I am not do await for the invocation.
The problem is that the "connection.subscribeAsync" argument is the following:
delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
I use Custom Attribute the find out if the action is async action or sync
and if it is async I use reflection to build Task from Action;
but at this point, its looks like I have to choose between two bad options,
The first is is use GetAwaiter().GetResults();
and the second is to do the method - async void and wrap the invocation with try and catch so I will catch exceptions when they occur before the synchronization Context.
I would love to hear any suggestions to deal with these issues.
code snaps:
async void MsgEvent(object sender, EncodedMessageEventArgs eArgs)
{
try
{
if (IsAsyncAction(request.Action))
{
await (Task)request.Action.GetMethodInfo()
.Invoke(request.Action, new object[] { eArgs });
}
.
.
.
}
catch (Exception e)
{
_logger.LogError(e.Message);
}
}
var subscription = connection.SubscribeAsync(request.Topic, MsgEvent);
/// <summary>
/// Expresses interest in the given <paramref name="subject" /> to the NATS Server, and begins delivering
/// messages to the given event handler.
/// </summary>
/// <remarks>The <see cref="T:NATS.Client.IAsyncSubscription" /> returned will start delivering messages
/// to the event handler as soon as they are received. The caller does not have to invoke
/// <see cref="M:NATS.Client.IAsyncSubscription.Start" />.</remarks>
/// <param name="subject">The subject on which to listen for messages.
/// The subject can have wildcards (partial: <c>*</c>, full: <c>></c>).</param>
/// <param name="handler">The <see cref="T:System.EventHandler`1" /> invoked when messages are received
/// on the returned <see cref="T:NATS.Client.IAsyncSubscription" />.</param>
/// <returns>An <see cref="T:NATS.Client.IAsyncSubscription" /> to use to read any messages received
/// from the NATS Server on the given <paramref name="subject" />.</returns>
/// <seealso cref="P:NATS.Client.ISubscription.Subject" />
IAsyncSubscription SubscribeAsync(string subject, EventHandler<EncodedMessageEventArgs> handler);