views:

212

answers:

4

I want to handle exceptions thrown by any controller action with an ErrorView model and an error view. The idea was to have something like:

[InformClientOfExceptions(typeof(MyErrorHandler))]
public ActionResult MyAction(Int32 someId)
{
    //...code
}

Then maybe have some class MyErrorHandler which implements a new interface IErrorView:

public class MyErrorHander : IErrorView
{
    public ActionResult OnException(Exception ex)
    {
        //..code which converts exception to some error view model and returns the view

When an exception is thrown by the action, the attribute cooks up the class specified and passes the exception to it, the exception is then handled (in the basic case formatted and output). Now yes, exceptions should never occur, or at least be properly handled, but I would like a better way of writing this. I don't want to use a custom error page as I would like to extend this pattern to allow for more complex responses to certain types of exception. Any ideas how best to approach this?

A: 

Did you try [HandleError]?

hunter
A: 

Hey,

Create a class that inherits from FilterAttribute and implements the IExceptionFilter attribute (something like that). This combination is used to log exceptions, and you can take in the type of an object to use for logging exceptions as you have specified.

Brian
+1  A: 

[HandleError] will look for the Error view by default. You can specify the view, and restrict by exceptions with parameters

[HandleError(ExceptionType = typeof(ArgumentException), View = "ErrorViewForThatException"]

You can put that attribute on either actions or controller classes. It doesn't exactly do what you want, but it comes extremely close.

Matt Briggs
A: 

Aside from if you use a construct that is included by default in MVC like the [HandleError] methodology what you are actually discussing is Aspect Orientated Programming (AOP). To achieve an AOP solution similar to that you will need to use a postbuild weaving framework that will merge in code to achieve your desired results such as PostSharp or LinFu.AOP. To achieve that without a build weaving framework you would need to handle it through interfaces and using Dynamic Proxies such as Castle.DynamicProxy or LinFu.DynamicProxy.

Chris Marisic