0

I built a custom Exception and I'm throwing an instance of this class whenever I consider that the my application is in an 'exceptional state'. This exception is being thrown in an application logic class (service in my case). Now, I also have the default ASP MVC exception redirection in place, but in case of these custom exceptions, I don't want it to redirect to the 'Error' page, but to show a message in a div (for example in my Layout.cshtml page). I was thinking on adding the exception message to TempData["ApplicationError"]. I want to write this code only once, not all over my controller action methods. So, in my base controller class I overridden protected void OnException(ExceptionContext filterContext) and my code looks like this:

protected override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.Exception is InvalidOperationException)
            TempData["ApplicationError"] = filterContext.Exception.Message;
        else
            base.OnException(filterContext);
    }

My problem is that I still get redirected to the default error page when this exception is thrown. I DON'T want this to happen. What I want is to display the custom exception's message in a friendly div on the same view the user is on. Do you have any ideas on how can I achieve this?

2 Answers 2

0

What i did in a similar situation in, I added a property to my ViewModel( i added to the base class where all other viewmodels are inheriting from) for error messsage and success message. Whenever there is an error (either application / system) i set value to this property and show this in my view. I will always return the viewmodel from controller thus not letting error page to be displayed.

public class BaseViewModel
{
  public string ErrorMessage { set;get;}
  public string SuccessMessage {set;get;}
  public bool IsValid { set;get;}
} 

public class UserViewModel: BaseViewModel
{
  // user properties
}

And in my controller

public ActionResult Get(int id)
{

  UserViewModel ovjUser;
  try
  {
    objUser=MyService.GetUser(id);
    if(!objUser.IsValid)
    {
       objUser.ErrorMessage="This User Account is not Valid";
    }
  }
  catch(Exception ex)
  {
   // log error
    objUser.ErrorMessage="Application is buzy now!.Pls try later";
  }
  return View(objUser);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. My problem with this approach is that I need to copy/paste try-cacth-AddError in all methods throwing this exception. I don't want this. I need something like a central(infrastructural) place to handle this always. In most cases, I don't even have a view model that backs my view-related-data.
Having a ViewModel is a better idea because it will give you strongly typed views.
Just don't need the VMs now, especially when they seem to be working around my problem.
0

Try indicating that you have handled the exception by setting the ExceptionHandled property:

protected override void OnException(ExceptionContext filterContext)
{
    if (filterContext.Exception is InvalidOperationException)
    {
        filterContext.ExceptionHandled = true;
        var viewResult = new ViewResult();
        viewResult.ViewData["ApplicationError"] = filterContext.Exception.Message;
        filterContext.Result = viewResult;
    }
}

An important aspect is that since there was an exception inside the controller action, it didn't get to the point where an action result was returned. So you no longer know whether the action had to render a view, return JSON, redirect or whatever. So you could assume it wanted to render a view by setting the filterContext.Result property. Obviously if you had a view model associated to this view you won't be able to reconstruct it. So make sure that your view is organized in such a manner that if there's something inside ViewData["ApplicationError"] don't even attempt to do anything with your view model as you won't have it => remember your application crashed in the middle of the execution of the action.

1 Comment

Thanks, I set a breakpoint in the exception handling scope, it gets there, but I still get yellow screen of death with the exception... I don't know if I still should see this if I run it locally(localhost/...)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.