fs.readFileSync ()에 대한 파일을 캡처하지 않는 방법은 무엇입니까?


135

node.js 내에서 readFile () 은 오류를 캡처하는 방법을 보여 주지만, 오류 처리에 관한 readFileSync () 함수에 대한 주석은 없습니다 . 따라서 파일이 없을 때 readFileSync ()를 사용하려고하면 오류가 발생 Error: ENOENT, no such file or directory합니다.

발생하는 예외를 어떻게 캡처합니까? doco는 어떤 예외가 발생했는지 명시하지 않으므로 어떤 예외를 포착해야하는지 모르겠습니다. try / catch 문의 일반적인 '모든 가능한 예외 예외 처리'스타일을 좋아하지 않습니다. 이 경우 파일이 존재하지 않을 때 발생하는 특정 예외를 포착하고 readFileSync를 수행하려고합니다.

연결 시도를 제공하기 전에 시작시에만 동기화 기능을 수행하므로 동기화 기능을 사용해서는 안되는 의견은 필요하지 않습니다.


1
내 새로운 답변fs.existsSync() 에서 볼 수 있듯이 사용할 수도 있습니다
Francisco Presencia

답변:


206

기본적으로 fs.readFileSync파일을 찾을 수 없으면 오류가 발생합니다. 이 오류는 Error프로토 타입에서 발생하며를 사용하여 발생 throw하므로 catch하는 유일한 방법은 try / catch블록을 사용하는 것입니다.

var fileContents;
try {
  fileContents = fs.readFileSync('foo.bar');
} catch (err) {
  // Here you get the error when the file was not found,
  // but you also get any other error
}

불행히도 프로토 타입 체인을보고 어떤 오류가 발생했는지 감지 할 수 없습니다.

if (err instanceof Error)

할 수있는 최선의 방법이며 대부분의 오류에 해당됩니다. 따라서 나는 당신이 그 code속성으로 가서 그 가치를 확인 하는 것이 좋습니다 .

if (err.code === 'ENOENT') {
  console.log('File not found!');
} else {
  throw err;
}

이 방법으로이 특정 오류 만 처리하고 다른 모든 오류를 다시 발생시킵니다.

또는 오류 message속성에 액세스 하여 자세한 오류 메시지를 확인할 수도 있습니다. 이 경우 다음과 같습니다.

ENOENT, no such file or directory 'foo.bar'

도움이 되었기를 바랍니다.


1
고마워, 내가 찾던 정보 야. 방금 특정 유형의 오류 일 것이라고 가정했습니다. 나는 또한 try / catch가 어떻게 작동하는지 오해했다는 것을 깨달았습니다. 특정 오류 유형 (la java)을 잡을 수 있다고 생각했습니다. 정보 Golo에 감사드립니다. :-)
Metalskin

2
또한 EACCES파일이 있지만 권한이 없어서 읽을 수없는 경우를 대비하여 if 문에서 코드를 검사해야합니다.
Gergely Toth

21

나는 이것을 처리하는이 방법을 선호합니다. 파일이 동 기적으로 존재하는지 확인할 수 있습니다.

var file = 'info.json';
var content = '';

// Check that the file exists locally
if(!fs.existsSync(file)) {
  console.log("File not found");
}

// The file *does* exist
else {
  // Read the file and do anything you want
  content = fs.readFileSync(file, 'utf-8');
}

참고 : 프로그램도 파일을 삭제하면 주석에 언급 된대로 경쟁 조건이 있습니다. 그러나 파일을 삭제하지 않고 파일을 쓰거나 덮어 쓰면 완전히 괜찮습니다.


2
이제 fs.existsSync는 더 이상 사용되지 않습니다 . "fs.exists ()는 사용되지 않지만 fs.existsSync ()는 사용되지 않습니다."
falkodev

17
전혀 나아지지 않습니다. existSync와 readFileSync 호출 사이에 파일이 디스크에서 제거되면 어떻게됩니까? 귀하의 코드는 이제 경쟁 조건이 발생하기를 기다리고 있습니다 ...
tkarls

2
@tkarls 예, 완전히 그렇습니다 .2015 년에 Node.js를 배우고있을 때 작성되었으며 경쟁 조건이 있습니다. 그러나 주목해야 할 두 가지 사항 :이 경쟁 조건의 가능성은 너무 작아 기본적으로 무시할 수 있으며 두 번째 및 첫 번째 감독은 요즘 코드를보다 유연하게 만들기 위해 async / await와 함께 try / catch를 사용한다는 것입니다 "기타"예외 (노드가 예외 친화적이므로)
Francisco Presencia

1
경쟁 조건은 그들이 할 때까지 중요하지 않습니다. 이와 같은 답변은 소프트웨어에 버그가 많은 이유, 컴퓨터를 자주 다시 시작해야하는 이유, 보안 취약점이 너무 많은 이유 등입니다. 스택 오버플로에는 잠재적으로 유해한 답변에 대한 플래그가 있어야합니다.
Jonathan Tran

N 년 후 또 다른 의견은 더 많은 것을 배우고 나서 (답변에 메모를 추가 함). 이것은 쓰기 전용 파일 시스템 프로그램과 관련하여 완전히 괜찮지 만 파일을 제거 할 수 있다면 경쟁 조건이 있으며 요즘 작성하는 코드가 아닙니다 (특히 동기화 때문에!). 또한 files비동기 및 시도 / 캐치를 더 쉽게 만들기 위해 배운 모든 내용으로 패키지 를 작성했습니다 .
Francisco Presencia

11

오류를 파악한 다음 어떤 유형의 오류인지 확인해야합니다.

try {
  var data = fs.readFileSync(...)
} catch (err) {
  // If the type is not what you want, then just throw the error again.
  if (err.code !== 'ENOENT') throw err;

  // Handle a file-not-found error
}

... 그것을 '오류를 던져라';
drudru

비동기 버전의 함수에서 동일한 오류를 잡을 수있는 방법이 있습니까?
Ki Jéy

1
@ KiJéy 비동기 코드는 콜백의 첫 번째 인수로 오류를 전달하므로 동일한 동작이 발생하는지 확인하십시오.
loganfsmyth

4

이 시나리오에는 즉시 호출 된 람다를 사용합니다.

const config = (() => {
  try {
    return JSON.parse(fs.readFileSync('config.json'));
  } catch (error) {
    return {};
  }
})();

async 버전:

const config = await (async () => {
  try {
    return JSON.parse(await fs.readFileAsync('config.json'));
  } catch (error) {
    return {};
  }
})();

솔루션이 ECMAScript 6 용임을 게시물에 추가하고 싶을 수 있습니다. 01/01/18 현재, 브라우저 사용 범위가 약 77 % 인 IE의 지원은 없습니다 ( caniuse.com/#feat=arrow-functions ). 궁금합니다. IE 사용자를 어떻게 수용합니까?
Metalskin

2
@Metalskin Webpack + 바벨. 그러나 fs노드 모듈입니다
sdgfsdh

아, 노드와 연락이 부족합니다. 질문을했을 때 노드가 ES6을 지원하지 않았다고 생각합니다 (잘못 될 수 있습니다). 킨다는 이것도 노드 질문 이었다는 것을 잊었다 ;-)
Metalskin

이것을 업데이트하는 fs.readFileAsync()것은 지금 fs.readFile() 이며 또한 node.js의 try / catch 안에 비동기 함수를 넣지 않아야합니다. try / catch는 비동기이기 때문에 오류가 발생하지 않습니다. 대신 콜백의 오류를 전달하고 처리하십시오. fs.readFile('/etc/passwd', (err, data) => { if (err) throw err; console.log(data); }); from : nodejs.org/dist/latest-v12.x/docs/api/…
KH B

약속이 거부되고 약속을 기다리는 경우 try-catch가 호출 될 것이라고 믿습니다.
sdgfsdh

0

NodeJS에있는 유일한 스레드를 차단하지 않으려면 Async를 대신 사용해보십시오 . 이 예를 확인하십시오.

const util = require('util');
const fs = require('fs');
const path = require('path');
const readFileAsync = util.promisify(fs.readFile);

const readContentFile = async (filePath) => {
  // Eureka, you are using good code practices here!
  const content = await readFileAsync(path.join(__dirname, filePath), {
    encoding: 'utf8'
  })
  return content;
}

나중에이 비동기 함수를 다른 함수의 try / catch와 함께 사용할 수 있습니다.

const anyOtherFun = async () => {
  try {
    const fileContent = await readContentFile('my-file.txt');
  } catch (err) {
    // Here you get the error when the file was not found,
    // but you also get any other error
  }
}

행복한 코딩!


0

JavaScript try… catch 메커니즘을 사용하여 비동기 API로 생성 된 오류를 가로 챌 수 없습니다. 초보자에게는 일반적인 실수는 오류 우선 콜백에서 throw를 사용하는 것입니다.

// THIS WILL NOT WORK:
const fs = require('fs');

try {
  fs.readFile('/some/file/that/does-not-exist', (err, data) => {
    // Mistaken assumption: throwing here...
    if (err) {
      throw err;
    }
  });
} catch (err) {
  // This will not catch the throw!
  console.error(err);
}

fs.readFile ()에 전달 된 콜백 함수가 비동기 적으로 호출되기 때문에 작동하지 않습니다. 콜백이 호출 될 때 try ... catch 블록을 포함한 주변 코드가 이미 종료되었습니다. 콜백 내에 오류가 발생하면 대부분의 경우 Node.js 프로세스가 중단 될 수 있습니다. 도메인이 사용 가능하거나 핸들러가 process.on ( 'uncaughtException')에 등록 된 경우 이러한 오류가 인터셉트 될 수 있습니다.

참조 : https://nodejs.org/api/errors.html

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.