Node.js 22へのアップグレードに関する問題
以下の問題は、モニターをNode.js 22にアップグレードする際に特有のものです。
未処理の開いたハンドル
症状:検証または実行中にモニターが失敗する原因: Node.js 22 ではプロセスライフサイクルに関する制約が厳しくなった
Node.js 22 にアップグレードする際に最もよく発生する問題は、未処理のオープンハンドルです。モニター スクリプトに未処理のオープン ハンドル (未解決の Promise、残留タイマー、クローズされていないネットワーク接続など) が含まれている場合、モニターは失敗します。
一般的な開閉式ハンドルの種類は以下のとおりです。
- 未解決の約束:すべての約束が適切に待機または処理されていることを確認する
- 残存タイマー:
setTimeoutおよびsetInterval呼び出しをすべてクリアします - 未接続: すべてのネットワーク接続、データベース接続、およびファイルハンドルを閉じます。
- HTTP/HTTPS接続:応答データを適切に処理し、接続を閉じる
HTTP/HTTPS接続は開いたままです
症状:モニターがハングアップまたはタイムアウトする原因:応答データが消費されていないか、keepAliveが有効になっていない
解決策A:応答データを利用する
httpまたはhttpsを使用するには、 dataイベントをリッスンしてください。それ以外の場合は、HTTPS接続は開いたままになります。
const https = require('https');
https.get('https://example.com', (res) => { console.log('Status Code:', res.statusCode); // Consume the response data res.on('data', (d) => { process.stdout.write(d); });}).on('error', (e) => { console.error('Error:', e);});解決策B:keepAliveを無効にする
リクエスト完了後にHTTP接続を閉じるには、 keepAliveオプションをfalseに設定してください。
const https = require('https');const { Agent } = require('https'); // or http for HTTP requests
const options = { hostname: 'example.com', path: '/', method: 'GET', agent: new Agent({ keepAlive: false }), // Disable keepAlive};
const req = https.request(options, (res) => { console.log(`Status: ${res.statusCode}`); res.on('data', (d) => { process.stdout.write(d); });});
req.on('error', (e) => { console.error(e);});
req.end();ストリームリソースがクリーンアップされませんでした
症状:リソースリークまたはモニターのハングアップ原因: finallyブロックでストリームが破棄されていない
解決
適切なリソースの解放を確実にするため、 finallyブロック内のストリームをクリーンアップします。
const got = require('got');
let downloadStream = got.stream("https://example.com/test.txt");
try { // Your stream processing logic here} finally { if (downloadStream) { downloadStream.destroy(); }}ソケットが正しく破壊されていません
症状:モニター検証が「オープンハンドル」エラーで失敗する。原因:成功コードパスでソケットのクリーンアップが欠落している。
すべてのコードパスにおいて、ソケットを適切に破棄してください。
問題のあるコード
// ❌ Problematic code - Socket not closed in success caseconst req = https.request(options, (res) => { try { const cert = res.socket.getPeerCertificate();
if (cert && Object.keys(cert).length > 0) { const validTo = cert.valid_to || cert.validTo; console.log("Raw certificate valid_to:", validTo); resolve({ validTo: validTo }); } else { reject(new Error("Could not get certificate information")); } } catch (err) { res.destroy(); if (res.socket) res.socket.destroy(); reject(err); }});推奨されるアプローチ
すべてのコードパスにクリーンアップ機能を追加する:
// ✅ Better approach - Proper cleanup in all casesconst req = https.request(options, (res) => { try { const cert = res.socket.getPeerCertificate();
// Always destroy the response and socket const cleanup = () => { try { res.destroy(); if (res.socket && !res.socket.destroyed) { res.socket.destroy(); } } catch (e) { console.log("Cleanup warning:", e.message); } };
if (cert && Object.keys(cert).length > 0) { const validTo = cert.valid_to || cert.validTo; console.log("Raw certificate valid_to:", validTo); cleanup(); resolve({ validTo: validTo }); } else { cleanup(); reject(new Error("Could not get certificate information")); } } catch (err) { res.destroy(); if (res.socket) res.socket.destroy(); reject(err); }});タイマーがクリアされていません
症状:モニターの実行が完了しない原因: setTimeout / setIntervalがクリアされていない
問題のあるコード
// ❌ Problematic codesetTimeout(() => { console.log('This might cause issues');}, 5000);推奨されるアプローチ
終了したらタイマーをリセットしてください。
// ✅ Better approachconst timerId = setTimeout(() => { console.log('This is properly handled');}, 1000);
// Clear the timer when doneclearTimeout(timerId);未解決の約束
症状:スクリプトは終了したように見えるが、検証が失敗する。原因: Promiseが適切に待機または処理されていない。
解決策:すべてのプロミスが.then() 、 .catch()であるか、 awaitで編集されていることを確認します。
Chromeランタイムのアップグレードに関する問題
次の問題は、スクリプト化ブラウザモニターを新しいChromeランタイムにアップグレードする場合に特有の問題です。
スクリプトブラウザ:要素とのインタラクションが失敗します
症状: findElementおよびその他のメソッドは新しいランタイムでは失敗しますが、従来のランタイムでは機能します原因: Seleniumのバージョン間の相違点の処理を Promise にしているウェブサイト
古いランタイムで作成されたモニターをChrome 100 (またはそれ以降) ランタイムに対して検証する場合、プロミス処理の違いにより、 findElementやページ上の要素を検索および操作するためのその他のメソッドが失敗する可能性があります。モニターがレガシー ランタイムでは成功し、新しいランタイムでは失敗し、要素がスクリーンショットに存在する場合は、Promise 処理ロジックを改善してください。
Seleniumウェブの意見 Promise Manager と制御フローにより、Promise を管理せずに、レガシー ランタイムで一部の関数を順番に実行できるようになりました。 この機能はSeleniumウェブ意見 4.0 で削除され、ランタイムでは使用できなくなりました。 すべての非同期関数と Promise は、 awaitまたは.then Promise チェーンを使用して管理する必要があります。 これにより、スクリプト関数が期待どおりの順序で実行されるようになります。
問題のあるコード
プロミスマネージャと制御フローにより、 $browser.getプロミスを返し、そのプロミスが正しく処理されていない場合でも、この部分的なスクリプトは正常に完了する可能性があります。
// ❌ Problematic code - Promises not handled$browser.get('http://example.com');
$browser.findElement($driver.By.css('h1'));推奨されるアプローチ
Chrome 100(またはそれ以降)ランタイムでは、Promiseを返すメソッドは、手順を適切に順序付けるために、awaitまたは.then構文を使用する必要があります。構文がより簡潔で使いやすいため、await の使用が推奨されますが、 .thenプロミス チェーンも引き続きサポートされています。
// ✅ Better approach - Using awaitawait $browser.get('http://example.com');
let el = await $browser.findElement($driver.By.css('h1'));スクリプトbrowser : 非推奨の警告 ($browser および $driver
症状:モニターログに非推奨警告が表示される原因:古いノードブラウザランタイムイメージを使用している
ブラウザランタイムのバージョン2.0.29以降では、 $browserおよび$driverに対する非推奨警告は削除されました。パブリックロケーションを使用するときにこれらの警告は表示されなくなりました。 プライベートロケーションの使用時にこれらの警告が表示された場合は、ノード ブラウザーのランタイム イメージを更新してください。
スクリプトbrowser : waitForAndFindElement および waitForPendingRequests
症状: $seleniumおよび$webDriver使用時にメソッドが使用できない原因: New Relicカスタム メソッドがSeleniumウェブワイド 4.1 ベース API に含まれていない
waitForAndFindElementとwaitForPendingRequestsメソッドは、Chrome 72以前のスクリプト対応ブラウザランタイムで提供されるNew Relic独自のメソッドです。Chrome 100 以降のランタイムでは$driverおよび$browserと併用できますが、 Selenium Web の 4.1 API を$seleniumおよび$webDriverと直接併用する場合は利用できません。 この変更によりNew RelicのSeleniumウェブ意見実装と基本的なSeleniumウェブ意見実装がより適切に調整されます。
新しいランタイムでwaitForAndFindElementまたはwaitForPendingRequests引き続き使用するには、 コード例をモニターに貼り付けてください。
APIランタイムアップグレードの問題
以下の問題は、スクリプト化されたAPI新しいNode.jsランタイムにアップグレードする際に特有のものです。
スクリプト API: requestとの違い got
症状: requestモジュール機能を使用したAPIスクリプトが新しいランタイムで失敗する原因:非推奨のrequestモジュールからgotモジュールへの移行
Node.js 10 以前のスクリプトAPIランタイムは、 request Node.js モジュールを使用して、 APIテストに使用できる $http オブジェクトを提供していました。
Node.js 16 以降のスクリプト API ランタイムでは、 requestの代わりにgot使用します。requestモジュールは 2020 年に非推奨となり、新しい API やブラウザベースのランタイムには含まれなくなりました。$httpオブジェクトは、 gotによって駆動されながら、 requestのようなカスタムエクスペリエンスを提供し、基本的な使用例に対する後方互換性を提供しつつ、非推奨のモジュールの使用を回避します。requestの高度な使用例すべてがサポートされているわけではありません。スクリプトの例と変換ガイドが用意されています。
ヒント
$httpオブジェクトは、Node.js 16 以降のスクリプト API ランタイムでrequest直接使用しようとする顧客に対しても、 requestと同様のエクスペリエンスを返します。
スクリプト API: 予期しないトークン JSON.parse
症状: JSON.parseを使用すると予期しないトークンエラーが発生する原因:コンテンツタイプが の場合、レスポンスボディは既に自動的に解析されている application/json
応答本文との対話中にJSON.parse関数を使用しようとすると、 Node.js 16 以降のランタイムを使用するスクリプトAPIモニターで予期しないエラーが発生します。 コンテンツタイプのレスポンスヘッダーがapplication/jsonの場合、 $httpオブジェクトはレスポンスボディに解析済みの JSON を返します。レスポンスボディを解析するためにJSON.parseを使用しようとする追加の呼び出しは、レスポンスボディが既に解析されているため、このエラーで失敗します。
コンテンツタイプのレスポンスヘッダーがapplication/jsonでない場合、レスポンスボディは自動的に解析されないため、 JSON.parse関数を使用する必要があります。
スクリプトAPI: HEADまたは GET
症状: HTTP HEADまたはGET requestsボディ関連のエラーで失敗する。原因:新しいランタイムが、 HEAD / GET requestsでのボディを禁止する HTTP 仕様を強制する。
HTTP HEADまたはGETリクエストにはリクエストボディを含めることはできません。Node 10以前のランタイムで使用されていたrequestモジュールではこれが可能でしたが、新しいランタイムではエラーが発生します。最も一般的な提案は以下のとおりです。
- リクエストに本文を含めないでください。たとえ空であってもです。
HEADまたはGETリクエストで不要なオプションは使用しないでください。json: true
スクリプト API: クエリ文字列 (qs) の違い
症状:クエリ文字列オプションが新しいランタイムで機能しない原因:オプション名がqs:から変更されました searchParams:
Node 10以前のランタイムでは、クエリ文字列の設定はqs:オプションを使用して渡されていました。Node 16ランタイムの場合は、代わりにsearchParams:オプションを使用してください。オプション名だけを変更すれば良い。クエリ文字列の内容を更新する必要はありません。
スクリプト API: Cookie jar の違い
症状: jar: trueを使用した Cookie 処理が機能しない原因: Node 16 ランタイムで Cookie jar の実装が変更された
Node 10 以前のランタイムでは、オプションjar: trueを使用して、リクエスト間で Cookie を Cookie jar に保存できました。
Node 16 ランタイムでは、 tough-cookieモジュールを使用して Cookie jar を作成し、代わりにリクエストでその Cookie jar を参照する必要があります。 cookiesという名前のクッキージャーを作成した場合は、オプションで次のように参照します。 cookieJar: cookies
スクリプト API: フォームの違い
症状:フォームベースのrequests失敗するか、動作が異なる。原因:フォーム処理に関するモジュールrequestとgotの違い。
Node 10 以前のランタイムの$httpオブジェクトに使用されるrequestモジュールと、Node 16 ランタイムの$httpオブジェクトに使用されるgotモジュールの違いにより、API モニターのフォームを使用したリクエストで問題が発生する可能性があります。
そうであれば、 form-dataモジュールを使用してフォームを作成し、リクエストに含めてください。以下に示す部分的な例をご覧ください。
const FormData = require('form-data');
let form = new FormData();form.set('fieldName1','value1');form.set('fieldName2','value2');
let req = { headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'multipart/form-data', }, body: form}UUID モジュールのバージョンの違い
症状:モジュールuuidのインポートエラー原因: Node 16ランタイムでモジュールuuidの構文が更新されました
Node 16 ランタイムには、更新されたrequire構文の使用を強制するuuidモジュールの新しいバージョンが含まれています。
Node 10以前: const uuid = require('uuid');
ノード 16 ( uuidv4の使用を想定): const { v4: uuidv4 } = require('uuid');