本篇目錄
介紹###
在一個web應用中,異常通常是在MVC控制器的action方法和Web API控制器中處理的。當異常發生時,應用程序會通知用戶發生的錯誤,也可能包含該錯誤產生的原因。
如果錯誤發生在一個常規的HTTP請求中,那么就會展示一個錯誤頁面。如果一個錯誤發生在Ajax請求中,那么服務端會給客戶端發送錯誤信息,然后處理后將錯誤展示給用戶。
在所有的web應用中處理異常是一個乏味反復的工作。ABP的異常處理是自動化的。你大多數情況下不需要處理任何異常。ABP會處理所有的異常,記錄異常信息日志,並返回給客戶端合適且格式化的響應,而且也會在客戶端處理這些響應並通知用戶。
開啟錯誤處理###
要開啟錯誤處理,必須開啟customErrors模式。
<customErrors mode="On" />
如果你不想在本機上處理錯誤,那么你可以將該值設置成“RemoteOnly”。
非Ajax請求###
如果請求是非Ajax的,那么就會顯示一個錯誤頁面。
展示異常信息
這里有個拋出任意異常的MVC控制器action。
public ActionResult Index()
{
throw new Exception("A sample exception message...");
}
當然,這個異常信息也可能被在該action中調用的其他方法拋出。ABP會處理這個異常,記錄到日志,然后顯示“Error.cshtml”視圖。你也可以自定義該錯誤視圖。一個錯誤視圖的例子如下(它是ABP模板中默認的錯誤視圖):
ABP會將該異常的細節隱藏給用戶,然后展示一個標准的(本地化)錯誤信息,除非你顯示拋出一個UserFriendlyException。
UserFriendlyException
UserFriendlyException是一個特殊類型的異常,它會直接展示給用戶。看下面的例子:
public ActionResult Index()
{
throw new UserFriendlyException("Ooppps! There is a problem!", "You are trying to see a product that is deleted...");
}
ABP會記錄這個錯誤日志,但是這次不會隱藏異常信息了,如下所示:
因此,如果你想要給用戶展示一個特殊的錯誤信息,只要拋出一個UserFriendlyException(或者派生自它的異常)就行了。
Error模型
ABP將一個ErrorViewModel對象傳給了Error視圖:
public class ErrorViewModel
{
public AbpErrorInfo ErrorInfo { get; set; }
public Exception Exception { get; set; }
}
ErrorInfo包含了可以展示給用戶的詳細信息, Exception對象是拋出的異常。如果你想,你也可以檢查它,然后展示額外的信息。比如,如果它是一個AbpValidationException,那么我們可以展示一個驗證錯誤的信息:
Ajax請求###
如果請求是Ajax請求,那么ABP會返回一個Json對象給客戶端。這對於MVC控制器和Web API控制器都是成立的。下面是返回一個錯誤對象的例子:
{
"targetUrl": null,
"result": null,
"success": false,
"error": {
"message": "An internal error occured during your request!",
"details": "..."
},
"unAuthorizedRequest": false
}
success:false表明發送了錯誤。
error對象提供了錯誤 信息和 細節。
當你使用ABP的基礎設施在客戶端發起Ajax請求時,客戶端會自動地處理這個Json對象,然后使用message API給用戶提示錯誤信息。
異常事件###
ABP處理任何異常時都會觸發AbpHandledExceptionData事件,注冊該事件后就會收到通知(查看事件總線(EventBus)獲取更多信息關於事件總線的信息)。例子:
public class MyExceptionHandler : IEventHandler<AbpHandledExceptionData>, ITransientDependency
{
public void HandleEvent(AbpHandledExceptionData eventData)
{
//TODO: 檢查 eventData.Exception!
}
}
如果你把這個樣例類放到你的應用中(一般放到Web項目中),HandleEvent方法就會被ABP處理的所有異常調用。這樣,你就可以研究Exception對象的細節了。