public void DisplaysSourceCodeLines_ForAbsolutePaths(string absoluteFilePath) { // Arrange var rootPath = Directory.GetCurrentDirectory(); // PhysicalFileProvider handles only relative paths but we fall back to work with absolute paths too using (var provider = new PhysicalFileProvider(rootPath)) { // Act var exceptionDetailProvider = new ExceptionDetailsProvider(provider, sourceCodeLineCount: 6); var stackFrame = exceptionDetailProvider.GetStackFrameSourceCodeInfo( "func1", absoluteFilePath, lineNumber: 10); // Assert // Lines 4-16 (inclusive) is the code block Assert.Equal(4, stackFrame.PreContextLine); Assert.Equal(GetCodeLines(4, 9), stackFrame.PreContextCode); Assert.Equal(GetCodeLines(10, 10), stackFrame.ContextCode); Assert.Equal(GetCodeLines(11, 16), stackFrame.PostContextCode); } }
public void DisplaysSourceCodeLines_PreAndPostErrorLine(ErrorData errorData) { // Arrange var stackFrame = new StackFrameSourceCodeInfo(); // Act var exceptionDetailProvider = new ExceptionDetailsProvider( new PhysicalFileProvider(Directory.GetCurrentDirectory()), logger: null, sourceCodeLineCount: 6); exceptionDetailProvider.ReadFrameContent( stackFrame, errorData.AllLines, errorData.ErrorStartLine, errorData.ErrorEndLine); // Assert Assert.Equal(errorData.ExpectedPreContextLine, stackFrame.PreContextLine); Assert.Equal(errorData.ExpectedPreErrorCode, stackFrame.PreContextCode); Assert.Equal(errorData.ExpectedErrorCode, stackFrame.ContextCode); Assert.Equal(errorData.ExpectedPostErrorCode, stackFrame.PostContextCode); }
/// <summary> /// Initializes a new instance of the <see cref="DeveloperExceptionPageMiddleware"/> class /// </summary> /// <param name="next"></param> /// <param name="options"></param> /// <param name="loggerFactory"></param> /// <param name="hostingEnvironment"></param> /// <param name="diagnosticSource"></param> /// <param name="filters"></param> public DeveloperExceptionPageMiddleware( RequestDelegate next, IOptions <DeveloperExceptionPageOptions> options, ILoggerFactory loggerFactory, IWebHostEnvironment hostingEnvironment, DiagnosticSource diagnosticSource, IEnumerable <IDeveloperPageExceptionFilter> filters) { if (next == null) { throw new ArgumentNullException(nameof(next)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } if (filters == null) { throw new ArgumentNullException(nameof(filters)); } _next = next; _options = options.Value; _logger = loggerFactory.CreateLogger <DeveloperExceptionPageMiddleware>(); _fileProvider = _options.FileProvider ?? hostingEnvironment.ContentRootFileProvider; _diagnosticSource = diagnosticSource; _exceptionDetailsProvider = new ExceptionDetailsProvider(_fileProvider, _options.SourceCodeLineCount); _exceptionHandler = DisplayException; foreach (var filter in filters.Reverse()) { var nextFilter = _exceptionHandler; _exceptionHandler = errorContext => filter.HandleExceptionAsync(errorContext, nextFilter); } }
/// <summary> /// Initializes a new instance of the <see cref="DeveloperExceptionPageMiddleware"/> class /// </summary> /// <param name="next"></param> /// <param name="options"></param> /// <param name="loggerFactory"></param> /// <param name="hostingEnvironment"></param> /// <param name="diagnosticSource"></param> public DeveloperExceptionPageMiddleware( RequestDelegate next, IOptions <DeveloperExceptionPageOptions> options, ILoggerFactory loggerFactory, IHostingEnvironment hostingEnvironment, DiagnosticSource diagnosticSource) { if (next == null) { throw new ArgumentNullException(nameof(next)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } _next = next; _options = options.Value; _logger = loggerFactory.CreateLogger <DeveloperExceptionPageMiddleware>(); _fileProvider = _options.FileProvider ?? hostingEnvironment.ContentRootFileProvider; _diagnosticSource = diagnosticSource; _exceptionDetailsProvider = new ExceptionDetailsProvider(_fileProvider, _options.SourceCodeLineCount); }
private RequestDelegate BuildApplication() { try { _applicationServicesException?.Throw(); EnsureServer(); var builderFactory = _applicationServices.GetRequiredService <IApplicationBuilderFactory>(); var builder = builderFactory.CreateBuilder(Server.Features); builder.ApplicationServices = _applicationServices; var startupFilters = _applicationServices.GetService <IEnumerable <IStartupFilter> >(); Action <IApplicationBuilder> configure = _startup.Configure; foreach (var filter in startupFilters.Reverse()) { configure = filter.Configure(configure); } configure(builder); return(builder.Build()); } catch (Exception ex) { if (!_options.SuppressStatusMessages) { // Write errors to standard out so they can be retrieved when not in development mode. Console.WriteLine("Application startup exception: " + ex.ToString()); } var logger = _applicationServices.GetRequiredService <ILogger <WebHost> >(); logger.ApplicationError(ex); if (!_options.CaptureStartupErrors) { throw; } EnsureServer(); // Generate an HTML error page. var hostingEnv = _applicationServices.GetRequiredService <IHostingEnvironment>(); var showDetailedErrors = hostingEnv.IsDevelopment() || _options.DetailedErrors; var model = new ErrorPageModel { RuntimeDisplayName = RuntimeInformation.FrameworkDescription }; var systemRuntimeAssembly = typeof(System.ComponentModel.DefaultValueAttribute).GetTypeInfo().Assembly; var assemblyVersion = new AssemblyName(systemRuntimeAssembly.FullName).Version.ToString(); var clrVersion = assemblyVersion; model.RuntimeArchitecture = RuntimeInformation.ProcessArchitecture.ToString(); var currentAssembly = typeof(ErrorPage).GetTypeInfo().Assembly; model.CurrentAssemblyVesion = currentAssembly .GetCustomAttribute <AssemblyInformationalVersionAttribute>() .InformationalVersion; model.ClrVersion = clrVersion; model.OperatingSystemDescription = RuntimeInformation.OSDescription; if (showDetailedErrors) { var exceptionDetailProvider = new ExceptionDetailsProvider( hostingEnv.ContentRootFileProvider, sourceCodeLineCount: 6); model.ErrorDetails = exceptionDetailProvider.GetDetails(ex); } else { model.ErrorDetails = new ExceptionDetails[0]; } var errorPage = new ErrorPage(model); return(context => { context.Response.StatusCode = 500; context.Response.Headers["Cache-Control"] = "no-cache"; return errorPage.ExecuteAsync(context); }); } }
/// <summary> /// Startup hooks are pieces of code that will run before a users program main executes /// See: https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/host-startup-hook.md /// </summary> public static void Initialize() { if (!NativeMethods.IsAspNetCoreModuleLoaded()) { // This means someone set the startup hook for Microsoft.AspNetCore.Server.IIS // but are not running inprocess. Return at this point. return; } var detailedErrors = Environment.GetEnvironmentVariable("ASPNETCORE_DETAILEDERRORS"); var enableStartupErrorPage = detailedErrors?.Equals("1", StringComparison.OrdinalIgnoreCase) ?? false; enableStartupErrorPage |= detailedErrors?.Equals("true", StringComparison.OrdinalIgnoreCase) ?? false; var aspnetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); enableStartupErrorPage |= aspnetCoreEnvironment?.Equals("Development", StringComparison.OrdinalIgnoreCase) ?? false; var dotnetEnvironment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"); enableStartupErrorPage |= dotnetEnvironment?.Equals("Development", StringComparison.OrdinalIgnoreCase) ?? false; if (!enableStartupErrorPage) { // Not running in development or detailed errors aren't enabled return; } AppDomain.CurrentDomain.UnhandledException += (sender, eventArgs) => { var exception = (Exception)eventArgs.ExceptionObject; // Get the content root from IIS. var iisConfigData = NativeMethods.HttpGetApplicationProperties(); var contentRoot = iisConfigData.pwzFullApplicationPath.TrimEnd(Path.DirectorySeparatorChar); var model = new ErrorPageModel { RuntimeDisplayName = RuntimeInformation.FrameworkDescription }; var systemRuntimeAssembly = typeof(System.ComponentModel.DefaultValueAttribute).Assembly; var assemblyVersion = new AssemblyName(systemRuntimeAssembly.FullName).Version.ToString(); var clrVersion = assemblyVersion; model.RuntimeArchitecture = RuntimeInformation.ProcessArchitecture.ToString(); var currentAssembly = typeof(ErrorPage).Assembly; model.CurrentAssemblyVesion = currentAssembly .GetCustomAttribute <AssemblyInformationalVersionAttribute>() .InformationalVersion; model.ClrVersion = clrVersion; model.OperatingSystemDescription = RuntimeInformation.OSDescription; var exceptionDetailProvider = new ExceptionDetailsProvider( new PhysicalFileProvider(contentRoot), logger: null, sourceCodeLineCount: 6); // The startup hook is only present when detailed errors are allowed, so // we can turn on all the details. model.ErrorDetails = exceptionDetailProvider.GetDetails(exception); model.ShowRuntimeDetails = true; var errorPage = new ErrorPage(model); var stream = new MemoryStream(); // Never will go async because we are writing to a memory stream. errorPage.ExecuteAsync(stream).GetAwaiter().GetResult(); // Get the raw content and set the error page. stream.Position = 0; var content = stream.ToArray(); NativeMethods.HttpSetStartupErrorPageContent(content); }; }
private RequestDelegate BuildApplication() { try { EnsureApplicationServices(); EnsureServer(); var builderFactory = _applicationServices.GetRequiredService <IApplicationBuilderFactory>(); var builder = builderFactory.CreateBuilder(Server.Features); builder.ApplicationServices = _applicationServices; var startupFilters = _applicationServices.GetService <IEnumerable <IStartupFilter> >(); Action <IApplicationBuilder> configure = _startup.Configure; foreach (var filter in startupFilters.Reverse()) { configure = filter.Configure(configure); } configure(builder); return(builder.Build()); } catch (Exception ex) when(_options.CaptureStartupErrors) { // EnsureApplicationServices may have failed due to a missing or throwing Startup class. if (_applicationServices == null) { _applicationServices = _applicationServiceCollection.BuildServiceProvider(); } EnsureServer(); // Write errors to standard out so they can be retrieved when not in development mode. Console.Out.WriteLine("Application startup exception: " + ex.ToString()); var logger = _applicationServices.GetRequiredService <ILogger <WebHost> >(); logger.ApplicationError(ex); // Generate an HTML error page. var hostingEnv = _applicationServices.GetRequiredService <IHostingEnvironment>(); var showDetailedErrors = hostingEnv.IsDevelopment() || _options.DetailedErrors; var model = new ErrorPageModel(); var runtimeType = Microsoft.Extensions.Internal.RuntimeEnvironment.RuntimeType; model.RuntimeDisplayName = (runtimeType == "CoreCLR") ? ".NET Core" : runtimeType == "CLR" ? ".NET Framework" : "Mono"; #if NETSTANDARD1_3 || NETSTANDARD1_5 var systemRuntimeAssembly = typeof(System.ComponentModel.DefaultValueAttribute).GetTypeInfo().Assembly; var assemblyVersion = new AssemblyName(systemRuntimeAssembly.FullName).Version.ToString(); var clrVersion = assemblyVersion; #else var clrVersion = Environment.Version.ToString(); #endif model.RuntimeArchitecture = RuntimeInformation.ProcessArchitecture.ToString(); var currentAssembly = typeof(ErrorPage).GetTypeInfo().Assembly; model.CurrentAssemblyVesion = currentAssembly .GetCustomAttribute <AssemblyInformationalVersionAttribute>() .InformationalVersion; model.ClrVersion = clrVersion; model.OperatingSystemDescription = RuntimeInformation.OSDescription; if (showDetailedErrors) { var exceptionDetailProvider = new ExceptionDetailsProvider( hostingEnv.ContentRootFileProvider, sourceCodeLineCount: 6); model.ErrorDetails = exceptionDetailProvider.GetDetails(ex); } else { model.ErrorDetails = new ExceptionDetails[0]; } var errorPage = new ErrorPage(model); return(context => { context.Response.StatusCode = 500; context.Response.Headers["Cache-Control"] = "no-cache"; return errorPage.ExecuteAsync(context); }); } }