private static string BuildUrl(ExceptionRoute route, HttpContext context)
        {
            RouteData r = context.GetRouteData();

            ActionContext a = new ActionContext(context, r, new ActionDescriptor());

            UrlHelper helper = new UrlHelper(a);

            return(helper.Action(route.Action, route.Controller, new { area = route.Area, Url = context.Request.Path }));
        }
Exemple #2
0
        protected virtual void LoadExceptionRoutes(Assembly assembly)
        {
            foreach (var method in assembly.FindMethodsWithAttribute<CatchesAttribute>())
            {
                ExceptionRoute route = new ExceptionRoute { Method = method };

                foreach (var attr in method.GetAttributes<CatchesAttribute>())
                {
                    route.Attributes.Add(attr);
                }

                ExceptionRoutes.Add(route);
            }
        }
        public async Task Invoke(HttpContext context)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            try
            {
                await this._next(context).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Type exceptionType = ex.GetType();

                if (!ErrorHandlers.TryGetValue(exceptionType, out ExceptionRoute route))
                {
                    if (!HandlersSearched)
                    {
                        HandlersSearched = true;

                        foreach (Type t in TypeFactory.GetAllTypes())
                        {
                            foreach (MethodInfo m in t.GetMethods())
                            {
                                if (m.GetCustomAttribute <HandleExceptionAttribute>() is HandleExceptionAttribute handler)
                                {
                                    foreach (Type e in handler.ToHandle)
                                    {
                                        AllHandlers.TryAdd(e, m);
                                    }
                                }
                            }
                        }
                    }

                    List <Type> searchTypes = new List <Type>();
                    Type        toCheck     = exceptionType;

                    do
                    {
                        searchTypes.Add(toCheck);
                        toCheck = toCheck.BaseType;
                    } while (toCheck != null && typeof(Exception).IsAssignableFrom(toCheck));

                    List <ExceptionHandler> potentialHandlers = new List <ExceptionHandler>();

                    foreach (Type possibleHandlerType in searchTypes)
                    {
                        if (AllHandlers.TryGetValue(possibleHandlerType, out MethodInfo m))
                        {
                            potentialHandlers.Add(new ExceptionHandler(possibleHandlerType, m));
                        }
                    }

                    Type mostDerivedHandler = TypeFactory.GetMostDerivedType(potentialHandlers.Select(p => p.ExceptionType).ToList(), typeof(Exception));

                    MethodInfo selectedHandler = potentialHandlers.FirstOrDefault(p => p.ExceptionType == mostDerivedHandler)?.Method;

                    if (selectedHandler is null)
                    {
                        ErrorHandlers.TryAdd(exceptionType, null);
                    }
                    else
                    {
                        string ControllerName = selectedHandler.DeclaringType.Name;

                        if (ControllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase))
                        {
                            ControllerName = ControllerName.Replace("Controller", "");
                        }

                        string ActionName = selectedHandler.Name;
                        string AreaName   = string.Empty;

                        if (selectedHandler.DeclaringType.GetCustomAttribute <AreaAttribute>() is AreaAttribute attribute)
                        {
                            AreaName = attribute.RouteValue;
                        }

                        route = new ExceptionRoute()
                        {
                            Action     = ActionName,
                            Area       = AreaName,
                            Controller = ControllerName
                        };

                        ErrorHandlers.TryAdd(exceptionType, route);
                    }
                }

                if (route is null)
                {
                    throw;
                }
                else
                {
                    context.Response.Redirect(BuildUrl(route, context));
                }
            }
        }