【发布时间】:2019-07-29 15:17:21
【问题描述】:
在一个 asp.net mvc 应用程序中,我成功地处理了当我从 javascript 对控制器进行 jquery $.ajax 调用时发生的异常。当我从 javascript 进行 javascript fetch() 调用时,我想以相同的方式处理错误,但我不知道如何识别已进行了 fetch() 调用。
我使用派生自 HandleErrorAttribute 的类来处理所有控制器错误。这是通过将以下行添加到 global.asax Application_Start 来完成的:
GlobalFilters.Filters.Add(new Areas.Insurance.Helpers.MyHandleErrorAttribute());
在 MyHandleErrorAttribute 中,我重写了 OnException 方法,以便我可以区别对待 Ajax 错误,而不是常规的 get 或 post 错误。如果出现 ajax 错误,我希望返回一个包含 guid 的对象并在 javascript 中触发 $.ajax "error:" 回调。如果 javascript fetch() 调用导致错误,我希望 response.ok 返回“false”并传回包含错误 guid 的对象。如果错误不是 ajax 错误或 javascript fetch() 错误,我想重定向到我们的自定义错误页面。代码如下所示:
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.Exception == null)
return;
//log the error
Guid guid = MyClass.LogError(filterContext.Exception.GetBaseException());
if (filterContext.HttpContext.Request.IsAjaxRequest()
&& filterContext.Exception != null)
{
//this is an error from a $ajax call.
//500 is needed so that $ajax "error:" function is hit, instead of "success:"
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult()
{
Data = new MyErrorObject()
{
Guid = guid
}
,JsonRequestBehavior = JsonRequestBehavior.AllowGet
//JsonRequestBehavior.AllowGet prevents following sporadic error: System.InvalidOperationException: This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
};
//this stops Application_OnError from firing
filterContext.ExceptionHandled = true;
//this stops the web site from using the default IIS 500 error.
//in addition must set existingResponse="Auto" ("PassThrough also works) in web.config httpErrors element.
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
else
{
//if condition to avoid error "Server cannot set status after HTTP headers have been sent"
if (!filterContext.HttpContext.Response.IsRequestBeingRedirected)
{
filterContext.Result = new RedirectToRouteResult(
new System.Web.Routing.RouteValueDictionary
{
{"action", "Error500" },
{"controller", "Error" },
{ "Guid", guid}
});
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
filterContext.ExceptionHandled = true;
}
}
}
我的问题是,当使用 javascript fetch() 进行调用时,“IsAjaxRequest”返回 false,因此第一个“if”块没有被命中。相反,我将进入“else”块,它将 Http 响应设置为“OK”并重定向到我的错误页面,这两者都是不需要的(当我收到 fetch() 错误时,我想返回 500响应,当然重定向没有效果)。
我如何识别已进行了 javascript fetch() 调用?有没有类似“IsAjaxRequest”的东西?
下面是 javascript fetch 的样子:
let url = '/myDomain/ThrowException';
fetch(url)
.then(function (data) {
if(data.ok){
//do something with data
}
else{
handleHttpErrorFunction(data);
}
})
.catch(function (error) {
handleFetchErrorFunction(error);
});
这是我想用 fetch() 调用替换的(成功处理的)jquery ajax 调用:
$.ajax({
url: '/myDomain/ThrowException',
type: 'GET',
success: function (data) {
//do something with data
},
error: function (XMLHttpRequest, ajaxOptions, ex) {
ajaxerrorhandler(XMLHttpRequest);
}
【问题讨论】:
标签: javascript asp.net-mvc error-handling fetch