私は以下のアプローチに決めました...
// * *Global.asax 内
protected void Application_Error(object sender, EventArgs e)
{
Exception originalError = Server.GetLastError();
Exception replacedError;
if (ExceptionPolicy.HandleException(originalError, "Global Policy", out replacedError))
{
Exception ex = replacedError ?? originalError;
if (ex.InnerException != null)
{
ex = ex.InnerException;
}
var httpException = ex as HttpException;
HttpApplication httpApplication = this.Context.ApplicationInstance;
string message = Utility.GetFullMessage(httpApplication, ex, "::");
string messageHtml = Utility.GetFullMessage(httpApplication, ex, "<br/>");
LogEntry logEntry = new LogEntry();
logEntry.EventId = 100;
logEntry.Priority = 2;
logEntry.Message = ex.Message + "::" + message;
Logger.Write(logEntry);
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = Constants.ErrorGeneralKey; //"General"
routeData.Values["message"] = ex.Message;
routeData.Values["fullMessage"] = messageHtml;
Response.StatusCode = 500;
if (httpException != null)
{
Response.StatusCode = httpException.GetHttpCode();
switch (Response.StatusCode)
{
case 403:
routeData.Values["action"] = "Http403";
break;
case 404:
routeData.Values["action"] = "Http404";
break;
default:
routeData.Values["httpStatusCode"] = Response.StatusCode;
break;
}
}
IController errorController = new ErrorController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorController.Execute(rc);
}
}
// * *ヘルパー クラス内
public static string GetFullMessage(HttpApplication httpApplication, Exception ex, string delimiter)
{
return "StackTrace: " + ex.StackTrace
+ delimiter + "User: " + ((httpApplication.User == null) ? "<null>" : httpApplication.User.Identity.Name)
+ delimiter + "Data: " + GetExceptionData(ex.Data)
+ delimiter + "Version: " + httpApplication.Request.Browser.Version
+ delimiter + "Browser: " + httpApplication.Request.Browser.Browser
+ delimiter + "Major Version: " + httpApplication.Request.Browser.MajorVersion.ToString()
+ delimiter + "Minor Version: " + httpApplication.Request.Browser.MinorVersion.ToString()
+ delimiter + "Javascript Version: " + httpApplication.Request.Browser.JScriptVersion.ToString()
+ delimiter + "Ecma Script Version: " + httpApplication.Request.Browser.EcmaScriptVersion.ToString()
+ delimiter + "Platform: " + httpApplication.Request.Browser.Platform
+ delimiter + "Source: " + ex.Source
+ delimiter + "Form: " + httpApplication.Request.Form.ToString()
+ delimiter + "QueryString: " + httpApplication.Request.QueryString.ToString()
+ delimiter + "TargetSite: " + ex.TargetSite;
}
// * *エラー コントローラ内
public ActionResult General(string httpStatusCode, string message, string fullMessage)
{
errorViewModel.RootCause = Enums.RootCause.General;
errorViewModel.HttpStatusCode = httpStatusCode;
errorViewModel.Message = message;
errorViewModel.FullMessage = fullMessage;
return View("Error", errorViewModel);
}
public ActionResult Http404()
{
errorViewModel.RootCause = Enums.RootCause.NotFound;
return View("Error", errorViewModel);
}
public ActionResult Http403()
{
errorViewModel.RootCause = Enums.RootCause.Forbidden;
return View("Error", errorViewModel);
}