• /
  • EnglishEspañolFrançais日本語한국어Português
  • 로그인지금 시작하기

사용자의 편의를 위해 제공되는 기계 번역입니다.

영문본과 번역본이 일치하지 않는 경우 영문본이 우선합니다. 보다 자세한 내용은 이 페이지를 방문하시기 바랍니다.

문제 신고

런타임 업그레이드 오류 문제 해결

Node.js 22 업그레이드 문제

다음 문제는 모니터를 Node.js 22로 업그레이드할 때 발생하는 특정 문제입니다.

처리되지 않은 열린 손잡이

증상: 모니터가 유효성 검사 또는 실행 중에 실패합니다. 원인: Node.js 22는 프로세스 수명 주기에 대해 더 엄격합니다.

Node.js 22로 업그레이드할 때 가장 흔한 문제는 처리되지 않은 열린 핸들입니다. 모니터 스크립트에 처리되지 않은 열린 핸들(예: 해결되지 않은 프로미스, 남아 있는 타이머 또는 닫히지 않은 네트워크 연결)이 포함되어 있으면 모니터가 실패합니다.

일반적인 열린 손잡이 유형은 다음과 같습니다.

  • 미해결 약속: 모든 약속이 적절하게 대기되거나 처리되었는지 확인하십시오.
  • 잔여 타이머: 모든 setTimeoutsetInterval 호출을 지웁니다.
  • 닫히지 않은 연결: 모든 네트워크 연결, 데이터베이스 연결 및 파일 핸들을 닫습니다.
  • 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 case
const 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 cases
const 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 code
setTimeout(() => {
console.log('This might cause issues');
}, 5000);

권장되는 접근 방식

완료되면 타이머를 초기화하세요.

// ✅ Better approach
const timerId = setTimeout(() => {
console.log('This is properly handled');
}, 1000);
// Clear the timer when done
clearTimeout(timerId);

해결되지 않은 약속들

증상: 스크립트 실행은 완료된 것처럼 보이지만 유효성 검사에 실패합니다. 원인: 프로미스(Promise)를 제대로 기다리거나 처리하지 않았습니다.

해결책: 모든 약속이 .then(), .catch() 이거나 await인지 확인합니다.

Chrome 런타임 업그레이드 문제

다음 문제는 브라우저 브라우저 모니터를 최신 Chrome 런타임으로 업그레이드하는 경우에만 발생합니다.

스크립트 기반 브라우저: 요소와의 상호 작용 시도가 실패합니다.

증상: findElement 및 기타 메서드가 새 런타임에서는 실패하지만 구형 런타임에서는 작동합니다. 원인: 셀레니엄 웹 드라이브 버전 간의 Promise 처리 차이점

이전 런타임에서 생성된 모니터를 Chrome 100(또는 그 이후) 런타임에 대해 검증할 때 페이지의 요소를 찾고 상호 작용하는 findElement 및 기타 메서드가 프로미스 처리 차이로 인해 실패할 수 있습니다. 만약 해당 요소가 이전 런타임에서는 통과했지만 새 런타임에서는 실패했고, 해당 요소가 검색 결과에 존재한다면, 프로미스 처리 로직을 개선하세요.

셀레니엄 웹드라이버 약속 관리자와 제어 흐름을 통해 약속을 관리하지 않고도 일부 기능이 원형 런타임에서 순서대로 실행될 수 있었습니다. 이 기능은 셀레니엄 웹드라이버 4.0에서 제거되었으며 더 이상 런타임에서 사용할 수 없습니다. 모든 비동기 함수와 약속은 await 또는 .then 약속 체인으로 관리해야 합니다. 이렇게 하면 스크립트 기능이 예상 순서대로 실행됩니다.

문제가 있는 코드

프로미스 관리자와 제어 흐름 덕분에 $browser.get 이 프로미스를 반환하고 해당 프로미스가 올바르게 처리되지 않더라도 이 부분 스크립트가 성공적으로 완료될 수 있습니다.

// ❌ Problematic code - Promises not handled
$browser.get('http://example.com');
$browser.findElement($driver.By.css('h1'));

권장되는 접근 방식

Chrome 100(또는 그 이후 버전) 런타임 에서는 프로미스를 반환하는 모든 메서드는 단계 순서를 올바르게 처리하기 위해 await 또는 .then 구문을 사용해야 합니다. await를 사용하는 것이 구문이 더 깔끔하고 사용이 더 쉽기 때문에 권장되지만 .then 프로미스 체인도 여전히 지원됩니다.

// ✅ Better approach - Using await
await $browser.get('http://example.com');
let el = await $browser.findElement($driver.By.css('h1'));

스크립트 브라우저: 사용 중단 경고($browser$driver

증상: 모니터 로그에 사용 중단 경고가 나타남 원인: 이전 버전의 Node.js 브라우저 런타임 이미지를 사용 중

$browser$driver 에 대한 사용 중단 경고는 브라우저 런타임 버전 2.0.29 이상부터 제거되었습니다. 표시 위치를 사용할 때 더 이상 이러한 경고가 표시되지 않습니다. 로케이션을 사용할 때 이러한 경고를 받으면 노드 브라우저 런타임 이미지를 업데이트하세요.

스크립트된 브라우저: waitForAndFindElementwaitForPendingRequests

증상: $selenium$webDriver 을 사용할 때 메서드를 사용할 수 없습니다. 원인: 뉴렐릭 사용자 지정 메서드가 셀레니엄 웹드라이버 4.1 기본 API에 포함되어 있지 않습니다.

waitForAndFindElementwaitForPendingRequests 메서드는 Chrome 72 및 이전 버전의 스크립트 브라우저 런타임에서 제공되는 뉴럴릭 사용자 지정 메서드입니다. Chrome 100 이상 런타임에서는 $driver$browser 과 함께 계속 사용할 수 있지만 셀레니엄 웹드라이버 4.1 API를 $selenium$webDriver 와 직접 사용할 때는 사용할 수 없습니다. 이번 변경으로 뉴렐릭의 셀레니엄 웹 드라이브 구현과 기본 셀레니엄 웹 드라이브 구현이 더 잘 일치합니다.

새 런타임에서 waitForAndFindElement 또는 waitForPendingRequests 계속 사용하려면 코드 예제를 모니터에 붙여넣으세요.

API 런타임 업그레이드 문제

다음 문제는 스크립트 기반 API 모니터를 최신 Node.js 런타임으로 업그레이드할 때 발생하는 특정 문제입니다.

스크립팅된 API: request 과의 차이점 got

증상: request 모듈 기능을 사용하는 API 스크립트가 새 런타임 환경에서 실패합니다. 원인: 더 이상 사용되지 않는 request 모듈에서 got 모듈로의 마이그레이션

Node.js 10 및 이전 버전의 스크립트 API 런타임은 API테스트하는 데 사용할 수 있는 $http 객체를 제공하기 위해 request Node.js 모듈을 사용했습니다.

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 사용 시 예기치 않은 토큰 오류 발생 원인: content-type이 인 경우 응답 본문이 이미 자동으로 구문 분석되었습니다. application/json

Node.js 16 이상 런타임을 사용하는 스크립트 기반 API 모니터에서 응답 본문과 상호 작용하는 동안 JSON.parse 함수를 사용하려고 하면 예기치 않은 토큰 오류가 발생합니다. 콘텐츠 유형 응답 헤더가 application/json 인 경우 $http 객체는 응답 본문에 구문 분석된 JSON을 반환합니다. JSON.parse 사용하여 응답 본문을 구문 분석하려는 추가 호출은 응답 본문이 이미 구문 분석되었기 때문에 이 오류와 함께 실패합니다.

content-type 응답 헤더가 application/json 아닌 경우 응답 본문이 자동으로 구문 분석되지 않으므로 JSON.parse 함수를 사용해야 합니다.

스크립트 API: HEAD 또는 GET

증상: HTTP HEAD 또는 GET requests 본문 관련 오류로 실패합니다. 원인: 새로운 런타임 환경에서 HTTP 사양이 적용되어 HEAD/GET requests에 본문을 포함할 수 없습니다.

HTTP HEAD 또는 GET 요청에는 요청 본문을 포함할 수 없습니다. Node 10 및 이전 런타임에서 사용되는 request 모듈은 이를 허용했지만 새 런타임에서는 오류가 발생합니다. 가장 일반적인 제안은 다음과 같습니다.

  • 요청에 본문을 포함하지 마세요. 내용이 비어있더라도 마찬가지입니다.
  • HEAD 또는 GET 요청에서 불필요한 옵션을 피하세요. json: true

스크립트 API: 쿼리 문자열(qs) 차이점

증상: 새 런타임에서 쿼리 문자열 옵션이 작동하지 않음 원인: 옵션 이름이 qs: 에서 다음으로 변경됨 searchParams:

Node 10 또는 이전 런타임에서는 쿼리 문자열 설정이 qs: 옵션을 사용하여 전달되었습니다. Node 16 런타임의 경우 searchParams: 옵션을 대신 사용하십시오. 옵션의 이름만 바꾸면 됩니다. 쿼리 문자열의 내용은 업데이트할 필요가 없습니다.

증상: jar: true 사용한 쿠키 처리가 작동하지 않음 원인: Node 16 런타임에서 쿠키 저장소 구현이 변경됨

Node 10 또는 이전 런타임에서는 jar: true 옵션을 사용하여 요청 간에 쿠키를 쿠키 항아리에 저장할 수 있습니다.

Node 16 런타임에서는 tough-cookie 모듈을 사용하여 쿠키 항아리를 만든 다음 요청에서 해당 쿠키 항아리를 참조해야 합니다. 쿠키라는 이름의 쿠키 항아리를 만든 경우 옵션에서 이를 참조하세요. cookieJar: cookies

스크립트 API: 양식 차이점

증상: 폼 기반 requests 실패하거나 다르게 동작함 원인: 폼 처리와 관련하여 requestgot 모듈 간의 차이점

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 모듈이 포함되어 있습니다.

노드 10 및 이전: const uuid = require('uuid');

노드 16( uuidv4 사용 가정): const { v4: uuidv4 } = require('uuid');

Copyright © 2026 New Relic Inc.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.