Skip to content

Windows: splash window loadFile rejects with ERR_FAILED (unhandledRejection in log) #1642

Description

@ystknsh

Summary

Windows 版で起動時に unhandledRejection: ERR_FAILED (-2) loading 'file:///...splash.html' がログに記録される。視覚的には splash ウィンドウは表示されており、本体機能(puppeteer 含む)にも影響は確認されていないが、unhandledRejection がログに残るのは綺麗ではないため別途調査・修正したい。

Environment

  • OS: Windows 11
  • App version: 1.0.14-rc-2(rc-1 でも同様のログを未確認だが、Electron 41→42 アップグレード以降で発生している可能性あり)
  • 検出経路: rc-2 検証中にユーザーログから発見

Observed log

```
[2026-05-18 15:15:41.251] [error] unhandledRejection Error: ERR_FAILED (-2) loading 'file:///C:\Users\ystkn\AppData\Local\mulmocast_app\app-1.0.14-rc-2\resources\app.asar.vite\build\splash.html'
at rejectAndCleanup (node:electron/js2c/browser_init:2:89485)
at finishListener (node:electron/js2c/browser_init:2:89647)
at WebContents.stopLoadingListener (node:electron/js2c/browser_init:2:90034)
at WebContents.emit (node:events:521:24)
```

エラータイムスタンプは rc-2 起動完了(Logger initialized)の約 2.5 秒後。unhandledRejection であって致命的クラッシュではない。

User impact

  • 視覚的: splash 画像は実際に表示されている(ユーザー確認済み)
  • 機能: puppeteer 経路 / 本体機能ともに正常
  • 影響: ログにエラー行が 1 件残る、それ以上の症状なし

Likely cause

src/main/main.tscreateSplashWindow で:

```ts
const createSplashWindow = async () => {
const splashWindow = new BrowserWindow({ ... });
if (isDev) {
await splashWindow.loadFile(path.join(__dirname, "../../splash.html"));
} else {
await splashWindow.loadFile(path.join(__dirname, "splash.html"));
}
splashWindow.center();
return splashWindow;
};
```

loadFile() の Promise が ERR_FAILED で reject されているのに、上位の app.on("ready", () => { void (async () => { ... await createSplashWindow() ... })(); }) で try/catch が無いため、async function 内の reject が unhandledRejection として浮上する。

ファイル自体は vite.main.config.tscopy-splash-html プラグインで .vite/build/splash.html にコピーされており、パスは正しいはず(資源として実在し、視覚的にも splash が出ている)。Electron 42 系で loadFile の Promise resolve/reject タイミングが変わった可能性、または asar 越し file:// ロード時の初回レースが疑わしい。

Suggested fix candidates

短期(リリースには載らない、別 PR で対応):

  1. createSplashWindowawait loadFile を try/catch で囲んで握り潰す
    • リスク低、ログのノイズは消える
    • ただし「画面に splash が出ているのに reject される」根本原因は隠蔽するだけ
  2. loadFile が reject した場合に 1 回だけリトライ
    • ERR_FAILED が一過性であれば確実に消える
  3. loadURL('file://' + ...) への切替えで file:// プロトコルの取り扱いを統一する

中期:

  • Electron 41 と 42 で挙動差があるか調査(41 → 42 のリリースノート確認)
  • asar 内の file:// ロードで似た問題が他にもないか調査(renderer 側の loadFile / loadURL を点検)

Out of scope

  • 1.0.14 リリースには含めない(既存挙動と同じく splash は表示される、機能影響なし)
  • 1.0.15 サイクルの定常タスクとして扱う

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions