Reporting Errors in Exception Filter Attribute

AAlderman

Posted on
Jun 17 2016

I've come across a problem using RayGun in a WebApi project. My app is architected such that I centralized Exception handling in a ExceptionFilterAttribute. This makes my controller code real clean; when an exception occurs, the ExceptionFilterAttribute and applies a set of rules to , including reporting it to Raygun like so:

raygunClient.SendInBackground(myCustomException,
                new List<string> {myCustomException.SeverityValue});

The problem is that the tags I was submitting weren't making it through to RayGun. I defined a property on my custom exception called severity, and I wanted that to be a tag, and and you can see I'm passing that value as the Tags parameter in SendInBackGround. But when I do this, the error that makes it to RayGun lists

Tags    None provided

Now, if I catch the error in the controller code and send the error to RayGun from there, it works fine, and my tags make it to RayGun. Reading your site, I found the following post:

https://raygun.com/forums/thread/8048

That post mentions that the tags may be "picked up automatically by the HttpModule." Does this mean that RayGun's HttpModule ignores tags when you call Send() or SendInBackground from an exception filter. Is there a way to stop that from happening?


Jason Fauchelle

Raygun

Posted on
Jun 17 2016

Hi AAlderman,

The issue you're most likely running into is that the RaygunProvider prevents the same Exception instance being sent multiple times. This is because there are scenarios both in the standard set up and by manually sending exceptions where you can easily double your exception usage - which can affect how much you pay, not to mention gives you a false count of how many exceptions are occurring.

For Raygun for WebAPI will be attaching into a bunch of exception handlers, one of which is the ExceptionFilterAttribute. This will be detecting the exception first and sending it to Raygun. When your filter gets the exception and tries to send it with tags, it gets denied due to preventing double sending. Losing the tags and custom data is a know flaw with not allowing double sending. I've made a note to look into perhaps making an option to override this, but I hope you understand that this feature is all in good faith of not doubling your usage.

There are a few options you could do to work around this. In your filter, before sending the exception, you could manually un-flag the exception to force it to be double sent. This will mean you get double the exceptions though - one without tags, and one without.

Type[] genericTypes = exception.Data.GetType().GetGenericArguments();
if (genericTypes.Length == 0 || genericTypes[0].IsAssignableFrom(typeof(string)))
{
  exception.Data.Remove("AlreadySentByRaygun");
}

Another option could be to remove the RaygunWebApiExceptionFilter from the HttpConfiguration.Filters collection so that it's only your ExceptionFilterAttribute that can detect, tag and send those exceptions to Raygun.

Another option could be to not use the RaygunWebApiClient.Attach method, and instead entirely listen to all the exception points and control them yourself. For WebAPI, there are a lot of places you can listen to exceptions though. Here is the source code for how Raygun for WebAPI attaches everything if you're interested: https://github.com/MindscapeHQ/raygun4net/blob/master/Mindscape.Raygun4Net.WebApi/RaygunWebApiClient.cs#L122

And another approach could be to only let the RaygunWebApiClient take care of listening to and sending all exceptions, but you can then listen to when the RaygunWebApiClient is about to send any exception and attach your tags to the e.Message.Details.Tags property at that point if possible. More information about listening to Raygun sending messages for WebAPI can be found here: https://raygun.com/docs/languages/net/webapi#modify-cancel-message

I hope that helps, please let me know if you have any questions about the approach you take. Note that I've assumed you're using the Raygun4Net.WebAPI package. You did mention the HttpModule though which this package does not have. If you're actually using the MVC or standard Raygun4Net packages, then let me know as a couple of the approaches I listed will be different.

-Jason Fauchelle


AAlderman

Posted on
Jun 18 2016

I'm using the Raygun4Net package. One approach that seems to work this: when I attach the raygun client, I wire in a filter like so:

        //attach Raygun client
        RaygunWebApiClient.Attach(config,
            () =>
            {
                //do other stuff which isn't relevant to this discussion
                //wire in the handlers
                _raygunClient.SendingMessage += RaygunFilter_ExcludeCustomExceptions;
                return _raygunClient;
            });

And that handler (I'm calling it RaygunFilter_... because it filters out exceptions)

    /// <summary>
    ///     Checks to see if the exception is one of our custom exceptions.  If so,
    ///     cancel it, because we'll handle it manually.
    /// </summary>
    private static void RaygunFilter_ExcludeCustomExceptions(object sender,
        RaygunSendingMessageEventArgs e)
    {
        var className = e.Message?.Details?.Error?.ClassName;
        if (!string.IsNullOrEmpty(className) && (
            className.Contains(typeof(CustomException1).Name) ||
            className.Contains(typeof(CustomException2).Name) ||
            className.Contains(typeof(CustomException3).Name) ||
            className.Contains(typeof(CustomExceptionBaseClass).Name)))
        {
            e.Cancel = true;
        }
    }

That seems to be effective in telling RayGun, "Leave the customs alone, I'll handle them."


Jason Fauchelle

Raygun

Posted on
Jun 20 2016

Hi AAlderman,

An interesting approach, thanks for sharing. Great to hear that you've got a work around to the issue.

Let us know any time you have further questions about Raygun.

-Jason Fauchelle


Reply