How to correctly catch exception raised by view or

2019-07-11 09:11发布

Ok, I am newbie in ASP.Net MVC 5 and working on a small already existing project so bear with me. I am finding it hard to understand/handle/decode exception raised in my code.

Here is the way the exception is getting handled in the project:

public class BaseController : Controller
{
    protected override void OnException(ExceptionContext filterContext)
    {
        if (!filterContext.ExceptionHandled)
        {
            filterContext.ExceptionHandled = true;
            Response.StatusCode = 500;    
            Response.StatusDescription = Constants.DISPLAYED_ERROR_MESSAGE_SHARED;

            if (filterContext.Exception.GetType() == typeof(ValidationException))
            { Response.StatusDescription += Constants.ADDITIONAL_DETAIL_ERROR_MESSAGE + filterContext.Exception.Message; }
            else
            { Response.StatusDescription += Constants.GENERIC_ERROR_MESSAGE; }
        }
    }
}

public static string DISPLAYED_ERROR_MESSAGE_SHARED = "We apologize for the inconvenience, but an error has occurred. <br />";
public static string GENERIC_ERROR_MESSAGE = "Please retry your previous action. If the issues persist, please contact the facility.";
public static string ADDITIONAL_DETAIL_ERROR_MESSAGE = "<br />Additional Details: ";

Error.cshtml

@model HandleErrorInfo
@{ 
    Layout = "~/Views/Shared/_ErrorLayout.cshtml";
}

<h2 style="color:darkred">An Error Has Occurred</h2>
<div style="color:black; font-size:110%;">
    @Html.Raw(Constants.DISPLAYED_ERROR_MESSAGE_SHARED)
    <br />
    @Constants.GENERIC_ERROR_MESSAGE

    <br />

    @if (Model.Exception.GetType() == typeof(ValidationException))
    {
        <div style="font-size:90%;">
            @Html.Raw(Constants.ADDITIONAL_DETAIL_ERROR_MESSAGE)
            @Model.Exception.Message
        </div>
    }
</div>

After studying I got to know that now any exception raised in the controller will be caught in above method thus protecting me from redundant use of try catch in our code. Fair Enough.

Issue No matter what ever the exception is raised in my project. I always see below message in browser enter image description here

Debug Results Everytime an exception is raised the value of filterContext.handled comes out to be true and thus the code never enters inside the onException Logic and directly Error.cshtml view is rendered. Also, I have noticed that when I check the value of filterContext.Exception I see the exact reason/issue for the exception.

Question 1: When an exception is raised and I can see during debugging that filterContext.Exception is telling me the exact issue then why I do not see it in my browser. Why do I have to debug all the time and check the Exeception by hovering my mouse on filterContext.

Question 2: Everytime I debug I find the filterContext.Exceptionhandled to be true. In what case it will be false?

Question 3: By mistake I added a HtmlHelper textbox for a property in a view. But the model associated with that view did not had that property. Now when I debug I can see that filterContext.Exception is telling me the exact issue. But as my filterContext.Exception already knows what mistake I did. Can't I display that in my UI rather than a generic message all the time.

Question 4 Apart from hovering over and getting to know my mistake/reason of exception, what benefit can I take from filterContet.Exception. Can't I somehow make my mistake visible in a graceful manner in UI atleast when code is in development and not in production.

EDIT Global Asax

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }
    }

And in the Application_Start method in strong textGlobal.asax.cs I have this line:

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

1条回答
The star\"
2楼-- · 2019-07-11 09:32

The ExceptionHandledproperty is set to true because there is already ActionFilter that set that before reaching your OnException method defined into your controller.

You can remove the global registration of HandleErrorAttribute from your Global.asax.cs file so when executing your OnException controller method the ExceptionHandled property will be false and you have to set it to true before you quit this method.

The correct solution to use I think is to create a new class let name it CustomHandleErrorAttribute that derives from HandleErrorAttribute and overrides the OnException method on that derived class.

After that you can change this line:

filters.Add(new HandleErrorAttribute());

to this line:

filters.Add(new CustomHandleErrorAttribute());
查看更多
登录 后发表回答