The next generation of the Teknik Services. Written in ASP.NET. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ErrorHandlerMiddleware.cs 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using IdentityServer4.Services;
  2. using Microsoft.AspNetCore.Builder;
  3. using Microsoft.AspNetCore.Diagnostics;
  4. using Microsoft.AspNetCore.Http;
  5. using Microsoft.AspNetCore.Mvc;
  6. using Microsoft.AspNetCore.Mvc.Internal;
  7. using Microsoft.AspNetCore.Routing;
  8. using Microsoft.Extensions.DependencyInjection;
  9. using Microsoft.Extensions.Logging;
  10. using Microsoft.Extensions.Options;
  11. using Newtonsoft.Json;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Globalization;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using Teknik.Configuration;
  19. using Teknik.IdentityServer.Controllers;
  20. using Teknik.Logging;
  21. using Teknik.Utilities;
  22. namespace Teknik.IdentityServer.Middleware
  23. {
  24. public class ErrorHandlerMiddleware
  25. {
  26. private readonly RequestDelegate _next;
  27. private readonly IRouter _router;
  28. public ErrorHandlerMiddleware(RequestDelegate next, IRouter router)
  29. {
  30. _next = next;
  31. _router = router;
  32. }
  33. public async Task Invoke(HttpContext httpContext, ILogger<Logger> logger, Config config, IIdentityServerInteractionService interaction)
  34. {
  35. var statusCodeFeature = new StatusCodePagesFeature();
  36. httpContext.Features.Set<IStatusCodePagesFeature>(statusCodeFeature);
  37. Exception exception = null;
  38. try
  39. {
  40. await _next(httpContext);
  41. }
  42. catch (Exception ex)
  43. {
  44. httpContext.Response.StatusCode = 500;
  45. exception = ex;
  46. }
  47. if (!statusCodeFeature.Enabled)
  48. {
  49. // Check if the feature is still available because other middleware (such as a web API written in MVC) could
  50. // have disabled the feature to prevent HTML status code responses from showing up to an API client.
  51. return;
  52. }
  53. // Do nothing if a response body has already been provided or not 404 response
  54. if (httpContext.Response.HasStarted)
  55. {
  56. return;
  57. }
  58. // Detect if there is a response code or exception occured
  59. if ((httpContext.Response.StatusCode >= 400 && httpContext.Response.StatusCode <= 600) || exception != null)
  60. {
  61. RouteData routeData = new RouteData();
  62. routeData.Values.Add("controller", "Error");
  63. routeData.Routers.Add(_router);
  64. var context = new ControllerContext();
  65. context.HttpContext = httpContext;
  66. context.RouteData = routeData;
  67. context.ActionDescriptor = new Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor();
  68. ErrorController errorController = new ErrorController(logger, config, interaction);
  69. errorController.ControllerContext = context;
  70. if (httpContext.Response.StatusCode == 500)
  71. {
  72. await errorController.Http500(exception).ExecuteResultAsync(context);
  73. }
  74. else
  75. {
  76. await errorController.HttpError(httpContext.Response.StatusCode).ExecuteResultAsync(context);
  77. }
  78. }
  79. }
  80. }
  81. // Extension method used to add the middleware to the HTTP request pipeline.
  82. public static class SetupErrorHandlerMiddlewareExtensions
  83. {
  84. public static IApplicationBuilder UseErrorHandler(this IApplicationBuilder builder, Config config)
  85. {
  86. var routes = new RouteBuilder(builder)
  87. {
  88. DefaultHandler = builder.ApplicationServices.GetRequiredService<MvcRouteHandler>(),
  89. };
  90. return builder.UseMiddleware<ErrorHandlerMiddleware>(routes.Build());
  91. }
  92. }
  93. }