tags:

views:

59

answers:

1

How can I create a fubumvc behaviour that wraps actions with a particular return type, and if an exception occurs while executing the action, then the behaviour logs the exception and populates some fields on the return object? I have tried the following:

public class JsonExceptionHandlingBehaviour : IActionBehavior
{
    private static readonly Logger logger = LogManager.GetCurrentClassLogger();
    private readonly IActionBehavior _innerBehavior;
    private readonly IFubuRequest _request;

    public JsonExceptionHandlingBehaviour(IActionBehavior innerBehavior, IFubuRequest request)
    {
        _innerBehavior = innerBehavior;
        _request = request;
    }

    public void Invoke()
    {
        try
        {
            _innerBehavior.Invoke();

            var response = _request.Get<AjaxResponse>();
            response.Success = true;
        }
        catch(Exception ex)
        {
            logger.ErrorException("Error processing JSON request", ex);

            var response = _request.Get<AjaxResponse>();
            response.Success = false;
            response.Exception = ex.ToString();
        }
    }

    public void InvokePartial()
    {
        _innerBehavior.InvokePartial();
    }
}

But, although I get the AjaxResponse object from the request, any changes I make don't get sent back to the client. Also, any exceptions thrown by the action don't make it as far as this, the request is terminated before execution gets to the catch block. What am I doing wrong?

For completeness, the behaviour is wired up with the following in my WebRegistry:

Policies
    .EnrichCallsWith<JsonExceptionHandlingBehaviour>(action =>
        typeof(AjaxResponse).IsAssignableFrom(action.Method.ReturnType));

And AjaxResponse looks like:

public class AjaxResponse
{
    public bool Success { get; set; }
    public object Data { get; set; }
    public string Exception { get; set; }
}
+1  A: 

This won't work with the current version of FubuMVC, unfortunately. The reason is that the call to _innerBehavior.Invoke() will proceed down the rest of the behavior chain including the call to render the JSON output back to the client.

With current FubuMVC, you can't wrap a behavior and modify its output before the render output behavior is executed.

I just talked with Jeremy (Miller) about this and we're going to add this capability to FubuMVC so that you can wrap a specific behavior (in this case, the behavior that calls the action) instead of wrapping the entire behavior chain (which is what's happening to you right now).

I'll comment back here on this StackOverflow question when we have added this feature.

chadmyers
FYI, there's ways you can work around this yourself in the meantime if this is critical. If it's not critical (i.e. you need it in the next day or two), then I'd advise waiting for it. I'll try to get it done this week for you.
chadmyers
Chad, not an urgent requirement it was more of an experiment that got the better of me, and I had convinced myself that it should work! Thanks for the response.
Jon M
Jon: I agree it should work, that's why I want to add this to FubuMVC :)
chadmyers