User-AgentをつけたりJSON.stringify(params)してみたが同様のエラーに阻まれた。

ブツ

インストール&実行

NAME='Electron.net.request.CONNECTION.REFUSED.20220827113011'
git clone https://github.com/ytyaru/$NAME
cd $NAME
npm install
npm start

準備

  1. GitHubアカウントを作成する
  2. repoスコープ権限をもったアクセストークンを作成する
  3. インストール&実行してアプリ終了する
    1. db/setting.jsonファイルが自動作成される
  4. db/setting.jsonに以下をセットしファイル保存する
    1. usernameに任意のGitHubユーザ名
    2. tokenrepoスコープ権限を持ったトークン
    3. repoに任意リポジトリ名(mytestrepo等)
  5. dst/mytestrepo/.gitが存在しないことを確認する(あればdstごと削除する)
  6. GitHub上に同名リモートリポジトリが存在しないことを確認する(あれば削除する)

実行

  1. npm startで起動またはアプリでCtrl+Shift+Rキーを押す(リロードする)
  2. git initコマンドが実行される
    • repo/リポジトリ名ディレクトリが作成され、その配下に.gitディレクトリが作成される
  3. createRepo実行後、以下エラーが出る(リモートリポジトリも作成されず)

net_error.png

A JavaScript error occurred in the main process

Uncaught Exception:
Error: net:ERR_CONNECTION_REFUSED
  at SimpleURLLoaderWrapper.<anonymous> (node:electron/js2c/browser_init:101:7169)
  at SimpleURLLoaderWrapper.emit (node:events:527:28)

経緯

上記のときにnet:ERR_CONNECTION_REFUSEDダイアログエラーが出た。

その後、以下のとき、createRepoするときはUser agent の必要性があると判明した。それがないときhttps.requestでは403エラーになっていた。

よく見返してみると、net.requestのときはUser-Agentを付与していなかった。なら、net.requestでもUser-Agentをつければイケるのでは? と思い至る。

そこで今回、改めてUser-Agentをセットした上でnet.requestを試してみた。結果は同じnet:ERR_CONNECTION_REFUSEDエラーだった……。

結局やはり原因不明。

src/js/app/github/github.js

コード抜粋。

await window.myApi.request({
    'method': 'POST',
    url: 'https://api.github.com/user/repos',
    headers: {
        'Authorization': `token ${this.token}`,
        'User-Agent': `${this.username}`,
        'Content-Type': 'application/json',
    },
    "body": JSON.stringify(params),
},(json, res)=>{
    console.debug(res)
    console.debug(json)
},(res)=>{
    console.debug(res)
})

Electronのnet.requestで謎エラー(net:ERR_CONNECTION_REFUSED)のときと比べてUser-AgentContent-Typeを追加した。でも結果は変わらなかった。Content-Typeをコメントアウトしても同じ。

さらに、念の為"body": params,"body": JSON.stringify(params)に変えてみたりもしてみたが、同じエラーだった。

考察

大抵バグるときは私のせいである。だから公式API net.request は動くと信じたい。現にGitHub APIのusersは叩けた。

なのにGitHub APIをusersからcreateRepoに変えるとnet:ERR_CONNECTION_REFUSEDエラーになる。原因として考えられるものは上記記事と違うコード部分にあるはず。違いを列挙すると以下。

そこで影響ありそうなところはすべて試してみたつもりだが、同じエラーだった。

一体https.requestのときと何が違うというのか。

もしやnet.request固有の問題なのか? Electron APIであるnet.requestは、Node.js APIであるhttps.requestを使わずに実装しているのかもしれない。だからhttps.requestでは成功するけど、net.requestではエラーになるのかな?

そもそもコンソールにエラーが出るわけでもなく、例外発生するでもなく、ダイアログでエラー表示されるので驚いた。JavaScript文脈よりもっと低レベルなところでエラーになっているのかもしれない。たとえばネットワークが切断されているとか。でも、そんなことはないのは確認済み。あるいはよく知らないけど、SSL/TLSのようなセキュリティ周りが古いとか? ネットワークにおける深い知識がないのでこれ以上想像できない。

net:ERR_CONNECTION_REFUSEDエラーは原因不明のため、これ以上は調査不能。

仮にこれが解決したところで、HTTPリクエスト後の処理を実装できない問題の調査にある問題があるため、まともに使えないし。

Electronでネット通信する方法

原因不明なのはモヤモヤするが、対処としては次のいずれかに限られるようだ。

ここまで調べたのだから、もう標準APInet.request, https.requestの使用は諦めるべきタイミングだろう。信じるものは裏切られる。