プロファイルの再利用、ヘッドレスモード、save_as() の切り分け

概要

  • 新しく作成したプロファイルは、最初の Edge プロセスでは正常に動作し、再利用後に障害が再現した。
  • ヘッドあり実行とヘッドレス実行のどちらでもクラッシュが再現した。
  • download.save_as() を別の方法に置き換えた場合も、調査の後半で Playwright の Download API を取り除いた場合も、障害は継続した。
  • 起動引数を簡略化し、ダウンロード動作を変更しても、パイプ経路での障害は解消しなかった。

テスト方法

比較のルールは単純だった。1 つの条件だけを変更し、残りの入力を固定したまま、成功した実行と失敗した実行の両方を記録した。

主な候補は次のとおりだった。

  1. 元のプロファイルに蓄積された状態
  2. ヘッドレスモード固有の動作
  3. Download.save_as() API
  4. 特定のダウンロード動作または起動引数

新しいプロファイルの再利用

最初のクラッシュは、以前から使用していたプロファイルで発生していた。その履歴の影響を取り除くため、空のテスト専用ユーザーデータディレクトリを指定して Edge を起動した。

最初の Edge プロセスでは、5 件すべてのダウンロードが完了した。

新しいプロファイル / 起動 1 / ダウンロード 1 -> 成功
新しいプロファイル / 起動 1 / ダウンロード 2 -> 成功
新しいプロファイル / 起動 1 / ダウンロード 3 -> 成功
新しいプロファイル / 起動 1 / ダウンロード 4 -> 成功
新しいプロファイル / 起動 1 / ダウンロード 5 -> 成功

Edge が正常に終了した後、同じプロファイルを再び使用した。

同じプロファイル / 起動 1 -> 成功
同じプロファイル / 起動 2 または 3 -> ダウンロード中にネイティブクラッシュ

このパターンは、個別に作成した複数のプロファイルで現れた。これにより、元の個人用プロファイルだけに限定された破損という可能性は否定された。Edge プロセスをまたいだ再利用は、依然として重要な条件だった。

ヘッドあり実行とヘッドレス実行

ヘッドレスブラウザーの実行は、通常の表示されるブラウザーとは異なる場合があるため、両方のモードをテストした。

モード 観測結果
ヘッドレス 最初の起動は成功し、その後の起動ではダウンロード中に切断された
ヘッドあり 最初の起動は成功し、その後の起動ではダウンロード中に切断された

後に両方のモードから収集したクラッシュダンプは、msedge.dll 内の同じ命令オフセットを示していた。この障害の発生にヘッドレスモードは必須ではなかった。

save_as() の除去

元の例外には Download.save_as() という名前が含まれていたため、当然疑わしい候補となった。異なる完了方法を用いて、ダウンロード処理を繰り返した。

テスト 観測結果
Download.save_as() で保存 Edge が終了し、Playwright が TargetClosedError を報告
download.path() を通じて一時ファイルを読み取り 同じネイティブクラッシュ
Playwright の Download API を使用せず、生の CDP コマンドを送信 同じネイティブクラッシュ

観測された順序から、エラーに save_as() が現れた理由を説明できる。

1. Edge でネイティブ障害が発生する
2. Edge プロセスが終了する
3. CDP 接続が閉じる
4. Playwright がブラウザーオブジェクトを閉じた状態として扱う
5. save_as() が TargetClosedError を報告する

save_as() はプロセスが閉じたことを検知したにすぎず、クラッシュを引き起こすために必要な要素ではなかった。

ダウンロード動作

Playwright 1.62.0 は、ダウンロードを設定する際に allowAndName に似た動作を使用する。より単純な allow の動作もテストした。

パイプ + allow        -> 再現
パイプ + allowAndName -> 再現
ポート + allowAndName -> 観測した実行では成功

ファイル名の処理だけでは、この結果を説明できなかった。

起動引数

Playwright は、自動化の安定性を確保するためにブラウザー引数を追加する。機能無効化リストや、Edge 固有の更新・互換性スイッチなど、候補となる引数を段階的に削除した。

起動引数を減らしたパイプ起動でも、クラッシュは継続した。クラッシュが発生する起動回が 2 回目から 3 回目にずれることはあったが、障害が消えることはなかった。これはすべての引数が無関係であると証明するものではないが、明らかなデフォルト引数のいずれか 1 つだけでは、観測されたパターンを説明できないことを示している。

結果

仮説 結果 根拠
元のプロファイルだけが破損していた 裏付けられず 新しいプロファイルでも再利用後に再現した
ヘッドレスモードが必須だった 除外 ヘッドありモードでも再現した
save_as() が必須だった 除外 Download API なしでもクラッシュが再現した
allowAndName だけがクラッシュを引き起こした 裏付けられず パイプ経由では allow でも再現した
明らかなデフォルト起動引数のいずれか 1 つが原因だった 裏付けられず 起動引数を減らしたパイプ起動でも再現した

残る疑問は、Playwright 自体が必要なのかどうかだった。次の手順では、自動化ライブラリを Node.js の標準モジュールからの直接的な CDP 通信に置き換えた。