/// <summary> /// Convert an exception object of the PortalErrorContract /// </summary> /// <param name="exception">The exception.</param> /// <returns>The PortalErrorContract.</returns> public static PortalErrorContract FromException(Exception exception) { var error = new PortalErrorContract(); PortalException extensionException = exception as PortalException; if (extensionException != null) { error.message = extensionException.Message; error.httpStatusCode = extensionException.httpStatusCode.ToString(); } else { // If we cannot positivly identify the exception type, we cannot show the message // in the exception to the end user. The exception (and it's messsage) will be // logged to MDS so nothing is lost. error.message = "Try again. Contact support if the problem persists."; error.httpStatusCode = System.Net.HttpStatusCode.InternalServerError.ToString(); error.operationTrackingId = string.Empty; } var debugModeSetting = ConfigurationManager.AppSettings["Microsoft.Azure.Portal.Configuration.PortalConfiguration.DevelopmentMode"]; if (string.Equals(debugModeSetting, "true")) { error.stackTrace = exception.ToString(); } return(error); }
/// <summary> /// Called when an exception occurs. /// </summary> /// <param name="filterContext">The action-filter context.</param> public override void OnException(ExceptionContext filterContext) { Debug.WriteLine(filterContext.Exception.ToString()); try { filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; try { filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError; } catch (HttpException httpException) { // Attempting to change the response status code after the response has started streaming to the client causes // an exception. We can't fix the stream the from this state, so ensure the original exception is logged. string logMessage = string.Format(CultureInfo.InvariantCulture, "Unable to report exception to the client. A HttpException occured while attempting to set the response status code to InternalServerError. " + "This can occur if the exception is thrown after the response to the client has started down the wire.{0}{0}" + "The response was in this state: {0}{1}{0}{0}" + "The HttpException was: {2}{0}{0}" + "The original exception was already logged and is repeated here for convenience only: {3}", Environment.NewLine, ResponseSummary(filterContext), httpException, filterContext.Exception.ToString()); Debug.WriteLine(logMessage); // The client typically sees the 200 and generates a parseerror at this point irrespective of whether we rethrow // or set ExceptionHandled to true (or to false). We may as well set it to true and save another logging attempt. filterContext.ExceptionHandled = true; return; } // Handle aggregate exceptions var aggregateException = filterContext.Exception as AggregateException; if (aggregateException != null) { filterContext.Exception = aggregateException.Flatten().InnerException; } PortalException extensionException = filterContext.Exception as PortalException; if (extensionException != null) { filterContext.HttpContext.Response.StatusCode = (int)extensionException.httpStatusCode; filterContext.HttpContext.Response.StatusDescription = NormalizeString(extensionException.Message); } filterContext.Result = new JsonResult() { JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = PortalErrorContract.FromException(filterContext.Exception) }; filterContext.ExceptionHandled = true; } catch (Exception exception) { Debug.WriteLine(exception); } }