只有累積,沒有奇蹟

2019年5月14日 星期二

[NETCore] ASP.NET Core 啟動異常 - HTTP Error 500.30 - ANCM In-Process Start Failure

問題 
在開發專案時跳出異常訊息,錯誤訊息為  HTTP Error 500.30 - ANCM In-Process Start Failure 這篇就針對此案例作簡單紀錄與分享若是有不清楚或是錯誤的地方歡迎討論予糾正

解決方法 
廢話不多說,先看案發現場的錯誤畫面
執行異常的程式代碼,看起來很單純的代碼
public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();
           
在錯誤訊息中提到應用程式無法啟動可能是因為 Application 啟動失敗、或是啟動時發生異常造成,建議解決方案為開啟事件檢視器進行確認,因此照著建議的除錯步驟找出問題的發生點

事件檢視器
開啟事件檢視器發現啟動 Application 時有多筆異常原因,過濾後有幫助的訊息如下
可以看到事件檢視器錯誤訊息為  Application '/LM/W3SVC/2/ROOT' with physical root 'D:\Marcus\git\SerilogWebAppLab\SerilogWebAppLab\SerilogWebAppLab\' hit unexpected managed exception, exception code = '0xe0434352'. Please check the stderr logs for more information. ,其中提到 exception code 為 0xe0434352,在 How do I fix a .NET windows application crashing at startup with Exception code: 0xE0434352 文章中提到此錯誤代碼為 .NET 在執行中異常的代碼,因此錯誤訊息也建議透過 stderr 紀錄來查看更多訊息 (一直挖挖蒐集麵包屑的概念),接著下一步是確認 stderr 相關 Log 紀錄。

ASP.NET Core Module stdout log
在 ASP.NET Core 中 stdout log 預設是關閉的,可以透過 Web.config 設定  stdoutlogEnable  開啟,如下
<aspNetCore processPath="dotnet"
      arguments=".\MyApp.dll"
      stdoutLogEnabled="true"
      stdoutLogFile=".\logs\stdout"
      hostingModel="InProcess"> 
stdoutLogEnabled 為啟用 stdout 紀錄,stdoutLogFile 是設定輸出 Log 路徑。如果是使用 Visual Studio IDE 使用 IIS Express 執行的話,則可以到專案檔底下的隱藏資料夾中的 applicationhost.config 搜尋 aspNetCore 區塊設定
ProjectName\.vs\ProjectName\config\applicationhost.config
修改後儲存 Web.config 檔案,重新執行一次應用程式,可以看到專案底下 Log 資料夾有新增指定檔案
檔名前面為 stdout 開頭,後面為時間戳記及處理事件代碼
stdout_20190513222912_28664.log
開啟 Log 檔案,內容顯示無法 Application 啟動時異常原因
透過 stdout Log 得知異常原因為 CreateDefaultBuilder 方法時預設會去讀取 appsettings.json 檔案,但由於 json 檔案格式錯誤造成 application 啟動時無法正常啟動,因而顯示 HTTP error 500.30 的狀況發生,修正後即可正常執行,宣告除蟲成功 ! 

備註 : Troubleshoot ASP.NET Core on IIS 內文有提到因為沒有限制記錄檔大小或是數量上限,啟用可能會造成應用程式或是伺服器失敗,請在確認完畢後關閉  stdoutlogEnable  為 false。

Improve 
調整代碼在啟動時加上 try catch 記錄錯誤訊息,讓之後遇到同樣事情可以更快發現 :)
public class Program
{
    public static void Main(string[] args)
    {
        InitialSerilog();

        try
        {
            CreateWebHostBuilder(args).Build().Run();
        }
        catch (Exception e)
        {
            Log.Error(e.Message);
            throw;
        }
    }

    private static void InitialSerilog()
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.Console()
            .WriteTo.File("logs/log_.txt", rollingInterval: RollingInterval.Day)
            .CreateLogger();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

參考

0 意見:

張貼留言

Copyright © m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com