private bool handleErrorIfOnHandledErrorPage(string errorEvent, Exception exception) { var handledErrorPages = new List <PageInfo> { MetaLogicFactory.CreateAccessDeniedErrorPageInfo(false), MetaLogicFactory.CreatePageDisabledErrorPageInfo(""), MetaLogicFactory.CreatePageNotAvailableErrorPageInfo(false) }; if (handledErrorPages.All(p => getErrorPage(p).GetUrl().Separate("?", false).First() != RequestState.Url.Separate("?", false).First())) { return(false); } RequestState.SetError(errorEvent + " during a request for a handled error page" + (exception != null ? ":" : "."), exception); transferRequest(getErrorPage(MetaLogicFactory.CreateUnhandledExceptionErrorPageInfo()), true); return(true); }
private bool handleErrorIfOnHandledErrorPage(string errorEvent, Exception exception) { var handledErrorPages = new[] { MetaLogicFactory.CreateAccessDeniedErrorPageInfo(false), MetaLogicFactory.CreatePageDisabledErrorPageInfo(""), MetaLogicFactory.CreatePageNotAvailableErrorPageInfo(false) }.Select(getErrorPage); var requestParameters = new HashSet <string>(getQueryParameters(RequestState.Url)); if (handledErrorPages.All( page => page.GetUrl().Separate("?", false).First() != RequestState.Url.Separate("?", false).First() || getQueryParameters(page.GetUrl()).Any(i => !requestParameters.Contains(i)))) { return(false); } RequestState.SetError(errorEvent + " during a request for a handled error page" + (exception != null ? ":" : "."), exception); transferRequest(getErrorPage(MetaLogicFactory.CreateUnhandledExceptionErrorPageInfo()), true); return(true); }
/// <summary> /// This method will not work properly unless the application is initialized, RequestState is not null, and the authenticated user is available. /// </summary> private void handleError(object sender, EventArgs e) { // The reason we don't write our error page HTML directly to the response, like ASP.NET does, is that this limits the functionality of the error pages // and requires them to be built differently than all other pages. We don't transfer to the error pages either, because application errors can occur at // any time in the ASP.NET life cycle and transferring to a page causes it to immediately execute even if it's not the normal time for this to happen. // Redirecting works, but has the drawback of not being able to send proper HTTP error codes in the response since the redirects themselves require a // particular code. TransferRequest seems to be the only method that gives us everything we want. ExecuteWithBasicExceptionHandling( delegate { // This code should happen first to prevent errors from going to the Windows event log. var exception = Server.GetLastError(); Server.ClearError(); RequestState.RollbackDatabaseTransactions(); DataAccessState.Current.ResetCache(); var errorIsWcf404 = exception.InnerException is System.ServiceModel.EndpointNotFoundException; // We can remove this as soon as requesting a URL with a vertical pipe doesn't blow up our web applications. var argException = exception as ArgumentException; var errorIsBogusPathException = argException != null && argException.Message == "Illegal characters in path."; // In the first part of this condition we check to make sure the base exception is also an HttpException, because we had a problem with WCF wrapping an // important non-HttpException inside an HttpException that somehow had a code of 404. In the second part of the condition (after the OR) we use // InnerException instead of GetBaseException because the ResourceNotAvailableException always has an inner exception that describes the specific // problem that occurred. The third part of the condition handles ResourceNotAvailableExceptions from HTTP handlers such as CssHandler; these are not // wrapped with another exception. if ((exception is HttpException && (exception as HttpException).GetHttpCode() == 404 && exception.GetBaseException() is HttpException) || exception.InnerException is ResourceNotAvailableException || exception is ResourceNotAvailableException || onErrorProneAspNetHandler || errorIsWcf404 || errorIsBogusPathException) { setStatusCode(404); return; } if (!handleErrorIfOnErrorPage("An exception occurred", exception)) { var accessDeniedException = exception.GetBaseException() as AccessDeniedException; var pageDisabledException = exception.GetBaseException() as PageDisabledException; if (accessDeniedException != null) { if (accessDeniedException.CausedByIntermediateUser) { transferRequest(MetaLogicFactory.CreateIntermediateLogInPageInfo(RequestState.Url), true); } else { var userNotYetAuthenticated = RequestState.UserAccessible && AppTools.User == null && UserManagementStatics.UserManagementEnabled; if (userNotYetAuthenticated && !ConfigurationStatics.IsLiveInstallation && !RequestState.ImpersonatorExists) { transferRequest(MetaLogicFactory.CreateSelectUserPageInfo(RequestState.Url), true); } else if (userNotYetAuthenticated && FormsAuthStatics.FormsAuthEnabled) { if (accessDeniedException.LogInPage != null) { // We pass false here to avoid complicating things with ThreadAbortExceptions. Response.Redirect(accessDeniedException.LogInPage.GetUrl(), false); CompleteRequest(); } else { transferRequest(MetaLogicFactory.CreateLogInPageInfo(RequestState.Url), true); } } else { transferRequest(getErrorPage(MetaLogicFactory.CreateAccessDeniedErrorPageInfo(!RequestState.HomeUrlRequest)), true); } } } else if (pageDisabledException != null) { transferRequest(MetaLogicFactory.CreatePageDisabledErrorPageInfo(pageDisabledException.Message), true); } else { RequestState.SetError("", exception); transferRequest(getErrorPage(MetaLogicFactory.CreateUnhandledExceptionErrorPageInfo()), true); } } }, true, true); }