수색…
통사론
- try {...} catch (오류) {...}
- try {...} finally {...}
- try {...} catch (오류) {...} finally {...}
- 새로운 오류 던짐 ([메시지]);
- 오류 ([메시지]);
비고
try
사용하면 실행되는 동안 오류를 테스트 할 코드 블록을 정의 할 수 있습니다.
catch
는 try
블록에서 오류가 발생하면 실행될 코드 블록을 정의 할 수 있습니다.
finally
결과에 관계없이 코드를 실행할 수 있습니다. 그러나 try 블록과 catch 블록의 제어 흐름 문은 finally 블록의 실행이 완료 될 때까지 일시 중단됩니다.
약속과의 상호 작용
예외는 약속 기반 비동기 코드에 대한 거부를 동기 코드로 만드는 것입니다. 약속 핸들러에서 예외가 발생하면 오류가 자동으로 포착되어 약속을 거부하는 대신 사용됩니다.
Promise.resolve(5)
.then(result => {
throw new Error("I don't like five");
})
.then(result => {
console.info("Promise resolved: " + result);
})
.catch(error => {
console.error("Promise rejected: " + error);
});
Promise rejected: Error: I don't like five
ECMAScript 2017의 일부인 것으로 예상되는 비동기 기능 제안 은 반대 방향으로이를 확장합니다. 거부 된 약속을 기다리는 경우 예외로 예외가 발생합니다.
async function main() {
try {
await Promise.reject(new Error("Invalid something"));
} catch (error) {
console.log("Caught error: " + error);
}
}
main();
Caught error: Invalid something
오류 개체
JavaScript의 런타임 오류는 Error
객체의 인스턴스입니다. Error
객체는있는 그대로 사용할 수도 있고 사용자 정의 예외의 기반으로 사용할 수도 있습니다. 어떤 유형의 값 (예 : 문자열)도 던질 수 있지만, 스택 추적과 같은 디버깅 정보가 올바르게 보존되도록하려면 Error
또는 파생 클래스 중 하나를 사용하는 것이 좋습니다.
Error
생성자의 첫 번째 매개 변수는 사람이 읽을 수있는 오류 메시지입니다. 추가 정보가 다른 곳에서 발견 될 수있는 경우에도 잘못된 내용에 대한 유용한 오류 메시지를 항상 지정해야합니다.
try {
throw new Error('Useful message');
} catch (error) {
console.log('Something went wrong! ' + error.message);
}
운영 명령 및 고급 생각
try catch 블록이 없으면 정의되지 않은 함수는 오류를 발생시키고 실행을 중지합니다.
undefinedFunction("This will not get executed");
console.log("I will never run because of the uncaught error!");
두 번째 줄을 실행하지 않고 오류가 발생합니다.
// Uncaught ReferenceError: undefinedFunction is not defined
다른 언어와 비슷한 try catch 블록이 있어야 코드를 계속 실행할 수 있습니다.
try {
undefinedFunction("This will not get executed");
} catch(error) {
console.log("An error occured!", error);
} finally {
console.log("The code-block has finished");
}
console.log("I will run because we caught the error!");
이제 오류를 발견하여 코드가 실행될 수 있는지 확인합니다.
// An error occured! ReferenceError: undefinedFunction is not defined(…)
// The code-block has finished
// I will run because we caught the error!
catch 블록에서 오류가 발생하면 어떻게 될까요?
try {
undefinedFunction("This will not get executed");
} catch(error) {
otherUndefinedFunction("Uh oh... ");
console.log("An error occured!", error);
} finally {
console.log("The code-block has finished");
}
console.log("I won't run because of the uncaught error in the catch block!");
나머지 catch 블록은 처리하지 않고 finally 블록을 제외하고 실행이 중단됩니다.
// The code-block has finished
// Uncaught ReferenceError: otherUndefinedFunction is not defined(…)
당신은 항상 당신의 try catch 블록을 중첩 할 수있다. 그러나 그것은 매우 지저분해질 것이기 때문에 그렇게해서는 안된다.
try {
undefinedFunction("This will not get executed");
} catch(error) {
try {
otherUndefinedFunction("Uh oh... ");
} catch(error2) {
console.log("Too much nesting is bad for my heart and soul...");
}
console.log("An error occured!", error);
} finally {
console.log("The code-block has finished");
}
console.log("I will run because we caught the error!");
이전 예제의 모든 오류를 catch하고 다음을 기록합니다.
//Too much nesting is bad for my heart and soul...
//An error occured! ReferenceError: undefinedFunction is not defined(…)
//The code-block has finished
//I will run because we caught the error!
그래서, 어떻게 우리가 모든 오류를 잡을 수 있습니다!? 정의되지 않은 변수와 함수의 경우 : 사용자가 정의 할 수 없습니다.
또한 try / catch 블록에서 모든 변수와 함수를 래핑하면 안됩니다.이 변수는 수정하기 전까지 한 번만 발생하는 간단한 예제이기 때문에 사용해야합니다. 그러나 객체, 함수 및 기타 알고있는 변수가 있지만 속성이나 하위 프로세스 또는 부작용이 있는지 여부를 알지 못하거나 일부 상황에서 일부 오류 상태가 예상되는 경우 오류 처리를 추상화해야합니다 어떤 종류의 방식으로. 다음은 매우 기본적인 예제와 구현입니다.
신뢰할 수 없거나 예외를 throw하는 메소드를 호출하는 보호 된 방법이없는 경우
function foo(a, b, c) {
console.log(a, b, c);
throw new Error("custom error!");
}
try {
foo(1, 2, 3);
} catch(e) {
try {
foo(4, 5, 6);
} catch(e2) {
console.log("We had to nest because there's currently no other way...");
}
console.log(e);
}
// 1 2 3
// 4 5 6
// We had to nest because there's currently no other way...
// Error: custom error!(…)
그리고 보호와 함께 :
function foo(a, b, c) {
console.log(a, b, c);
throw new Error("custom error!");
}
function protectedFunction(fn, ...args) {
try {
fn.apply(this, args);
} catch (e) {
console.log("caught error: " + e.name + " -> " + e.message);
}
}
protectedFunction(foo, 1, 2, 3);
protectedFunction(foo, 4, 5, 6);
// 1 2 3
// caught error: Error -> custom error!
// 4 5 6
// caught error: Error -> custom error!
우리는 오류를 잡아 내고 여전히 다소 다른 구문으로 모든 예상 코드를 처리합니다. 어느 쪽이든 작동하지만 더 고급 응용 프로그램을 빌드 할 때 오류 처리를 추상화하는 방법을 생각하기 시작할 것입니다.
오류 유형
JavaScript에는 6 개의 특정 핵심 오류 생성자가 있습니다.
EvalError
- 전역 함수eval()
에 관해 발생하는 오류를 나타내는 인스턴스를 만듭니다.InternalError
- JavaScript 엔진의 내부 오류가 발생할 때 발생하는 오류를 나타내는 인스턴스를 만듭니다. 예 : "너무 많은 재귀". ( Mozilla Firefox 에서만 지원됨)RangeError
- 숫자 변수 또는 매개 변수가 유효한 범위 밖에있을 때 발생하는 오류를 나타내는 인스턴스를 만듭니다.ReferenceError
- 잘못된 참조를 역 참조 할 때 발생하는 오류를 나타내는 인스턴스를 만듭니다.SyntaxError
-eval()
에서 코드를 파싱하는 동안 발생하는 구문 오류를 나타내는 인스턴스를 만듭니다.TypeError
- 변수 또는 매개 변수가 유효한 형식이 아닌 경우 발생하는 오류를 나타내는 인스턴스를 만듭니다.URIError
-encodeURI()
또는decodeURI()
에 잘못된 매개 변수가 전달 될 때 발생하는 오류를 나타내는 인스턴스를 만듭니다.
오류 처리 메커니즘을 구현하는 경우 어떤 종류의 오류를 코드에서 포착 할 수 있는지 확인할 수 있습니다.
try {
throw new TypeError();
}
catch (e){
if(e instanceof Error){
console.log('instance of general Error constructor');
}
if(e instanceof TypeError) {
console.log('type error');
}
}
이 경우 e
는 TypeError
의 인스턴스가됩니다. 모든 오류 유형은 기본 생성자 Error
확장하므로 Error
인스턴스이기도합니다.
이를 염두에두면 대부분의 경우 Error
가 e
가 아닌 것으로 확인하는 것이 쓸모 없다는 것을 알 수 있습니다.