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.