Перехват необработанных исключений уровня IIS - PullRequest
2 голосов
/ 30 апреля 2020

Я пытаюсь реализовать обработку ошибок в одном из наших ASP. NET веб-API (не основных) проектов (работающих. NET 4.7.2), чтобы в будущем не возникла ошибка, у нас было пару дней go.

Ошибка состояла в том, что этот код в файле Web.Config не был обновлен, но была обновлена ​​библиотека, поставляемая с проектом, когда он был опубликован, поэтому было несовпадение версий.

  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs"
        type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
        type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
    </compilers>
  </system.codedom>

Version=2.0.1.0 в обеих compiler строках было установлено на Version=1.0.8.0, а опубликованная версия DLL была 2.0.1.0. Это дает ошибку, которая выглядит следующим образом:

Image that shows the exception

Теперь я хотел бы обработать это исключение в коде и записать его в наш стек журналирования. , Я искал вокруг и нашел несколько различных методов отлова исключений в проекте web.api, но ни один из них, похоже, не сработал. Я попробовал:

В файле global.asax.cs:

        void Application_Error(object sender, EventArgs e)
        {
            Exception ex = Server.GetLastError();

            if (ex != null)
                Logger.WriteToFile(ex.Message, ex);
        }

Также в файле global.asax.cs:

        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);

            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        }

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception ex = (e.ExceptionObject as Exception);

            if (ex != null) 
                Logger.WriteToFile(ex.Message, ex);
        }

В WebApiConfig.Register функция, которая автоматически добавляется в Web.API (например, которая управляет настройкой маршрутизации):

        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Filters.Add(new GlobalExceptionFilterAttribute()); // <-- this line

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

    public class GlobalExceptionFilterAttribute : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            var exceptionType = context.Exception.GetType().ToString();
            var exception = context.Exception.InnerException ?? context.Exception;

            try
            {
                if (exception != null)
                    Logger.WriteToFile(exception.Message, exception);
            }
            finally
            {
                base.OnException(context);
            }
        }
    }

И в файле web.config я добавил модуль, который должен (теоретически ) обрабатывать ошибки уровня IIS (взято из Ошибка определения уровня IIS для обработки в ASP. NET):

  <system.webServer>
    <modules>
      <add type="ErrorHttpModule" name="ErrorHttpModule"/>
    </modules>
  </system.webServer>
public class ErrorHttpModule : IHttpModule
{
    private HttpApplication _context;

    public ErrorHttpModule() { }

    public void Init(HttpApplication context)
    {
        _context = context;
        _context.Error += new EventHandler(ErrorHandler);
    }

    private void ErrorHandler(object sender, EventArgs e)
    {
        Exception ex = _context.Server.GetLastError();

        if (ex != null)
            Logger.WriteToFile(ex.Message, ex);
    }

    public void Dispose()
    {
    }
}

И, похоже, ничего из этого не перехватывается ошибка, и зарегистрируйте ее. Как я могу поймать эту ошибку?

Я воспроизвел эту ошибку в совершенно пустом проекте Web.API в дополнение к нашему основному проекту. Пустой проект Web.API можно найти по адресу https://github.com/Loyalar/IISExceptionCapture.

Ответы [ 2 ]

0 голосов
/ 01 мая 2020

Вы можете использовать приведенный ниже код в начале вашего приложения. В Program.cs, Startup.cs или в файле Global.asax.

AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
    Debug.WriteLine(eventArgs.Exception.ToString());
};

см. Ссылку ниже для получения более подробной информации:

https://stackify.com/csharp-catch-all-exceptions/

перехватывает все необработанные исключения в ASP. NET Web Api

0 голосов
/ 30 апреля 2020

Устранение неполадок:

  1. включен stdoutLogEnabled и проверен журнал IIS.

  2. Вы также можете проверить события журнала окна.

См. - https://weblog.west-wind.com/posts/2020/Jan/14/ASPNET-Core-IIS-InProcess-Hosting-Issues-in-NET-Core-31

...