Increase timeout in nodejs built in fetch APIの解決方法【2025年最新版】
エラーの概要・症状
Node.jsのビルトインfetch APIを使用している際に、リクエストがタイムアウトしてしまう場合があります。このエラーは、特にネットワークが遅い環境や、接続先のサーバーが応答を返すまでに時間がかかる場合に発生します。エラーメッセージが表示されると、アプリケーションが期待通りに動作せず、ユーザーが利用できる機能が制限されてしまいます。
例えば、外部のAPIにデータをリクエストする際に、デフォルトのタイムアウト時間(通常は10秒程度)を超えてしまうと、リクエストが失敗し、エラーが発生します。このようなエラーは、特にウェブアプリケーションのパフォーマンスに影響を与えるため、早急に解決する必要があります。ユーザーは、エラーが発生することでアプリケーションの使用に支障をきたし、業務や作業が滞る可能性があります。
このエラーが発生する原因
Node.jsのビルトインfetch APIは、HTTPリクエストを送信するための簡便な方法を提供していますが、デフォルトの接続タイムアウトは比較的短いため、特定の状況下でリクエストがタイムアウトしてしまうことがあります。以下に、主な原因を説明します。
- デフォルトのタイムアウト設定: Node.jsのビルトイン
fetchAPIは、デフォルトで10秒のタイムアウトを持っています。この設定は、接続先が応答しない場合に自動的にリクエストをキャンセルします。 -
ネットワークの遅延: 特にインターネット接続が不安定な環境では、リクエストが遅延することがあります。接続先のサーバーが高負荷で応答が遅れる場合、タイムアウトが発生することがあります。
-
サーバーの応答時間: 接続先のAPIやサーバーの処理が遅い場合、リクエストがタイムアウトすることがあります。特に、データベースのクエリが重い場合や、サーバーがメンテナンス中である場合に発生しやすいです。
-
大きなデータの送受信: 大きなデータを送信または受信する場合、タイムアウトが発生することがあります。特に、ファイルのアップロードやダウンロードの際には、注意が必要です。
このような原因により、Node.jsのビルトインfetch APIを使用する際には、タイムアウトを適切に設定することが重要です。
解決方法1(最も効果的)
Node.jsでfetch APIを使用する際に、undiciパッケージを利用してタイムアウトを設定する方法があります。以下に具体的な手順を示します。
H3: 手順1-1(具体的なステップ)
- 最初に、
undiciパッケージをインストールします。ターミナルで以下のコマンドを実行します。
npm install undici
H3: 手順1-2(詳細な操作方法)
- 次に、以下のように
undiciからAgentをインポートし、fetch関数にタイムアウトを設定します。コードは以下のようになります。
import { Agent } from 'undici';
const response = await fetch('https://example.com', {
dispatcher: new Agent({ connectTimeout: 30000 }) // タイムアウトを30秒に設定
});
このコードでは、接続タイムアウトを30秒に設定しています。必要に応じて、タイムアウトの時間を調整してください。
H3: 注意点とトラブルシューティング
- タイムアウトの値はミリ秒単位で指定します。必要に応じて、適切な値に調整してください。
undiciを使用する際は、Node.jsのバージョンが17.0.0以上であることを確認してください。
解決方法2(代替手段)
もしundiciを使用せずに、グローバルなタイムアウトを設定したい場合、以下の手順を実行できます。
undiciをインポートし、setGlobalDispatcherでグローバルなタイムアウトを設定します。以下のコードを使用します。
import { fetch, setGlobalDispatcher, Agent } from 'undici';
setGlobalDispatcher(new Agent({ connect: { timeout: 20000 } })); // グローバルな接続タイムアウトを20秒に設定
このコードをモジュールの最初に記述することで、以降のすべてのfetchリクエストに対して20秒のタイムアウトが適用されます。
解決方法3(上級者向け)
Node.jsのバージョンが20以上の場合、AbortSignalを用いてより簡単にタイムアウトを設定できます。以下のコードを参考にしてください。
const response = await fetch(process.env.CORREOS_URLENVIOS, {
method: 'POST',
body: soap,
headers: {
'Authorization': 'Basic ' + Buffer.from(process.env.CORREOS_USERNAME + ':' + process.env.CORREOS_PASSWORD).toString('base64'),
'Content-Type': 'application/soap+xml; charset=utf-8',
'Accept': '*/*'
},
signal: AbortSignal.timeout(60000) // タイムアウトを60秒に設定
});
この方法では、AbortSignalを使用して、リクエストが60秒以内に完了しない場合に自動的にキャンセルされます。
エラーの予防方法
タイムアウトエラーを防ぐためには、以下の対策が有効です。
- **適切なタイムアウト設定**: 使用するAPIやサーバーの応答時間を考慮し、適切なタイムアウトを設定することが重要です。特に、外部サービスとの通信では、サーバーの応答が遅れることがあるため、余裕を持った設定が推奨されます。
- **ネットワークの監視**: ネットワークの状態を監視し、問題が発生した場合には迅速に対応できるようにすることが大切です。
- **定期的なメンテナンス**: アプリケーションやサーバーの定期メンテナンスを行い、パフォーマンスを向上させることで、タイムアウトのリスクを減少させます。
関連するエラーと対処法
- **Connection Reset Error**: 接続がリセットされるエラーが発生することがあります。この場合、サーバーやネットワークの状態を確認し、再試行することが有効です。
- **Network Timeout Error**: ネットワークタイムアウトが発生する場合、ルーターやモデムの再起動を行うか、ネットワーク設定を確認することが推奨されます。
まとめ
Node.jsのビルトインfetch APIでタイムアウトエラーが発生した場合、undiciを使用してタイムアウトを適切に設定することが重要です。また、適切なタイムアウトの設定やネットワークの管理を行うことで、エラーの発生を未然に防ぐことができます。エラーが発生した際は、紹介した解決方法を参考にして、迅速に対処してください。

コメント