[Javascript log]エラーハンドル

4137 ワード

try catchとエラーハンドル
エラーが発生した場合、JavaScriptはエラーの詳細を含むオブジェクトを生成します.次に、オブジェクトをパラメータとしてcatchブロックに渡します.
内部エラーとエラーオブジェクト全体に2つの主要なpropertyがあります.
name
エラー名.未定義の変数によるエラーの場合は、「ReferenceError」という名前になります.
message
エラー詳細を含むメッセージ
stack
現在の呼び出しスタック.エラーの原因となるネストされた呼び出し順序情報を持つ文字列をデバッグします.
try {
  lalala; // 에러, 변수가 정의되지 않음!
} catch(err) {
  alert(err.name); // ReferenceError
  alert(err.message); // lalala is not defined
  alert(err.stack); // ReferenceError: lalala is not defined at ... (호출 스택)

  // 에러 전체를 보여줄 수도 있습니다.
  // 이때, 에러 객체는 "name: message" 형태의 문자열로 변환됩니다.
  alert(err); // ReferenceError: lalala is not defined
}
let json = "{ bad json }";

try {

  let user = JSON.parse(json); // <-- 여기서 에러가 발생하므로
  alert( user.name ); // 이 코드는 동작하지 않습니다.

} catch (e) {
  // 에러가 발생하면 제어 흐름이 catch 문으로 넘어옵니다.
  alert( "데이터에 에러가 있어 재요청을 시도합니다." );
  alert( e.name );
  alert( e.message );
}
throwでエラーを作成します.
let json = '{ "age": 30 }'; // 불완전한 데이터

try {

  let user = JSON.parse(json); // <-- 에러 없음

  if (!user.name) {
    throw new SyntaxError("불완전한 데이터: 이름 없음"); // (*)
  }

  alert( user.name );

} catch(e) {
  alert( "JSON Error: " + e.message ); // JSON Error: 불완전한 데이터: 이름 없음
}
finallyのコードは、次の場合に実行されます.
エラーがない場合:try実行完了後
エラーが発生した場合:catchの実行が完了すると
try {
   ... 코드를 실행 ...
} catch(e) {
   ... 에러 핸들링 ...
} finally {
   ... 항상 실행 ...
}
try..catchがなくても、ほとんどのホスト環境ではグローバルエラーハンドラがサポートされているため、「失われた」エラーをキャプチャできます.window.onerrorはブラウザ環境のグローバルエラーハンドラです.
拡張カスタムエラーとエラー
カスタマイズ=>ユーザーが再加工した、、、
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}

// 사용법
function readUser(json) {
  let user = JSON.parse(json);

  if (!user.age) {
    throw new ValidationError("No field: age");
  }
  if (!user.name) {
    throw new ValidationError("No field: name");
  }

  return user;
}

// try..catch와 readUser를 함께 사용한 예시

try {
  let user = readUser('{ "age": 25 }');
} catch (err) {
  if (err instanceof ValidationError) { //instanceof 연산자는 생성자의 prototype 속성이 객체의 프로토타입 체인 어딘가 존재하는지 판별한다.
    alert("Invalid data: " + err.message); // Invalid data: No field: name
  } else if (err instanceof SyntaxError) { // (*)
    alert("JSON Syntax Error: " + err.message);
  } else {
    throw err; // 알려지지 않은 에러는 재던지기 합니다. (**)
  }
}
=>エラー・タイプを増やすたびに、ブランチ文を追加しますか?
=>エラーの非表示:実際に必要な情報は、「データの読み込み時」にエラーが発生したかどうかです.ほとんどの場合、エラーの理由を詳細に説明する必要はありません.
1)「データ読み込み」などの包括的なエラーを表す新しいクラスReadErrorを作成します.
2)関数readUserで発生したValidationError,SyntaxErrorなどのエラーはreadUser内部でキャプチャされ,その時点でReadErrorが生成される.
3)ReadErrorオブジェクトの原因であるPropertyエンティティエラーへの参照を保存します.
class ReadError extends Error {
  constructor(message, cause) {
    super(message);
    this.cause = cause;
    this.name = 'ReadError';
  }
}

class ValidationError extends Error { /*...*/ }
class PropertyRequiredError extends ValidationError { /* ... */ }

function validateUser(user) {
  if (!user.age) {
    throw new PropertyRequiredError("age");
  }

  if (!user.name) {
    throw new PropertyRequiredError("name");
  }
}

function readUser(json) {
  let user;

  try {
    user = JSON.parse(json);
  } catch (err) {
    if (err instanceof SyntaxError) {
      throw new ReadError("Syntax Error", err);
    } else {
      throw err;
    }
  }

  try {
    validateUser(user);
  } catch (err) {
    if (err instanceof ValidationError) {
      throw new ReadError("Validation Error", err);
    } else {
      throw err;
    }
  }

}

try {
  readUser('{잘못된 형식의 json}');
} catch (e) {
  if (e instanceof ReadError) {
    alert(e);
    // Original error: SyntaxError: Unexpected token b in JSON at position 1
    alert("Original error: " + e.cause);
  } else {
    throw e;
  }
}