#1. 예외처리
1. 예외처리(Exception Handling)란?
- 프로그램 실행 중 예기치 못한 에러가 발생했을 때 대처할 수 있게 처리하는 것을 뜻한다.
- Syntax Error: 구문오류. 코딩상의 실수이므로 수정하지 않으면 프로그램이 동작하지 않는다. (단순 오타)
- Runtime Error: 프로그램 작성 과정에서 논리상의 오류로 미쳐 대응하지 못한 상황이 발생하는 경우이다.
- 프로그램이 실행되다가 오류나는 부분을 만나면 멈춘다.
2. 기본(고전적) 예외처리
- 조건문을 사용하는 기본(고전적) 예외처리이다.
- 프로그램이 실행되기에 적합하지 않는 파라미터가 전달 된 경우 미리 약속된 값을 리턴한다
- 프로그램의 성공 / 실패 여부를 리턴값으로 판단하는 경우이다.
function example(x, y) {
if(x < 0 && y < 0) {
return 0
}
return x + y;
};
// 비정상인 상황에 대한 고전적 처리
const ex = example(-1, -2); // 비정상적인 호출
// 에러 상황에 대한 대응(메세지 처리)을 함수를 호출하는 곳에서 해야한다.
if(ex == 0) {
console.log("0보다 작으면 안됩니다.");
} else {
console.log(ex);
}
2. try - catch
- try 구문안에서 예외가 발생하면, catch 구문으로 넘어가 처리하는 방식이다.
- 반대로 try 구문안에서 예외가 발생하지 않는다면 catch 구문은 건너뛴다. (try - catch는 한쌍)
- catch( ) 는 무슨 에러가 발생했는지에 대한 설명이 담긴 객체이다.
- try - catch 문을 사용하면 에러가 발생해도 프로그램이 중단되지 않는다.
- finally 구문도 있는데, 에러의 발생 여부에 상관없이 마지막에 실행되는 구문이다.
- 필요하지 않는 경우 생략해도 된다.
// 변수 선언
const data = [1, 2, 3];
try {
for(let i = 0; i < 10; i++) {
console.log(data[i].toFixed(2)); // toFixed 할 배열 수 부족, 에러발생
}
// 에러가 발생하면 에러난 코드 밑으로는 실행되지 않는다.
console.log("try 블록 실행완료"); // 실행 안됨
} catch(err) { // ( )안에는 아무 이름을 넣어도 된다.
console.log(err); // 예외 정보 전체가 출력된다.
console.log(err.name); // 예외 이름
console.log(err.message); // 예외 메세지
console.log(err.description); // 예외 설명
} finally { // 생략가능
console.log("배열 탐색 종료");
}
// try-catch문을 사용하면 에러가 발생하더라도 프로그램이 중단되지 않는다.
console.log("프로그램 종료");
3. throw
- 직접 에러를 발생시킬 때 사용할 수 있다.
- 이 구문을 실제 에러로 인식하기 때문에 프로그램이 이 위치에서 중단된다.
- throw 밑에 있는 코드는 실행되지 않는다.
// 에러 객체를 생성
// 생성자 파라미터로 에러의 내용 전달
let err = new Error("에러났는데요?");
console.log(err.name); // Error(에러 객체 이름)
console.log(err.message); // 에러났는데요?(에러 객체 메세지)
// 개발자가 직접 에러를 발생시킬 수 있다.
throw err;
// 실행 안됨
console.log("프로그램 종료");
- throw 구문은 try - catch로 처리가 가능하다.
let err = new Error("에러났는데요?");
try {
// try 구문안에 throw를 넣어 에러 발생시킨다.
throw err;
} catch(err) {
console.log(err.name); // Error(에러 객체 이름)
console.log(err.message); // 에러났는데요?(에러 객체 메세지)
}
// 에러 상황을 try-catch로 처리했기 때문에 프로그램이 중단되지 않고 무사히 종료 할 수 있다.
console.log("프로그램 종료"); // 프로그램 종료
4. 예외객체를 활용한 예외처리
function example(x) {
if(x < 0) {
// 함수 안에서 에러를 강제로 발생시킬 경우, 이 함수를 호출하는 위치를 에러로 인식한다.
throw new Error("x가 0보다 작습니다.") // 파라미터로 에러 메세지 전달
}
return x;
}
// a에 null 값 대입
// 에러 점검이 끝난 후 try-catch 블록 밖에서 a의 값을 활용하려면 변수의 선언 위치가 try 블록보다 위에 있어야 한다. (변수의 스코프 규칙)
let a = null;
// try 블록 안의 코드는 최소화 하는 것이 프로그램 효율에 좋다. (결과 값은 try 블록 밖에서 사용하는것이 좋다.)
try {
// 0보다 작은 값 전달
// 호출 에러이기 때문에 대입이 안된다. (대입전에 에러)
a = example(-1);
} catch (err) {
// catch 구문으로 전달 되는 err 객체는 위 함수에서 생성한 Error 클래스의 객체이다.
console.log(err.name); // Error
console.log(err.message); // x가 0보다 작습니다
}
console.log(a); // null
5. 사용자정의 에러
- 에러의 종류를 세분화 하기 위해 Error 클래스의 기능을 상속(확장) 받아 직접 에러에 대한 경우의 수를 정의할 수 있다.
- 자식클래스가 생성자를 갖는 경우 부모의 생성자를 반드시 강제 호출해야한다.
class X_Small extends Error {
// 자식클래스가 생성자를 갖는 경우 부모의 생정자를 반드시 강제 호출해야한다. (super)
constructor(msg) {
super(msg);
super.name = "에러발생! x가 0보다 작은데요?" // 에러 이름 대입
}
}
class Y_Small extends Error {
constructor(msg) {
super(msg);
super.name = "에러발생! y가 0보다 작은데요?" // 에러 이름 대입
}
}
function example(x, y) {
if(x < 0) {
throw new X_Small("x가 0보다 작습니다."); // 에러 메세지 전달
}
if(y < 0) {
throw new Y_Small("y가 0보다 작습니다."); // 에러 메세지 전달
}
return x + y;
}
let a = null;
let b = null;
try {
a = example(-1, 1);
} catch (err) {
console.log(err.name); // 에러발생! x가 0보다 작은데요?
console.log(err.message); // x가 0보다 작습니다.
}
try {
b = example(1, -1);
} catch (err) {
console.log(err.name); //에러발생! y가 0보다 작은데요?
console.log(err.message); // y가 0보다 작습니다
}
console.log(a); // null
console.log(b); // null
6. 모듈을 활용한 예외처리
Error 클래스를 상속받아 사용자정의 에러 클래스를 만들고, 모듈을 통해 예외처리를 할 수 있다.
※ 입력값 검사하는 예외처리 예시
- Error 클래스를 상속받아 자식클래스를 확장시키고, 모듈에 등록한다
// Error 클래스를 상속
class BadRequestException extends Error {
// 자식클래스가 생성자를 갖는 경우 부모의 생성자를 호출해야 한다.
constructor(msg = "잘못된 요청 입니다.") { // 파라미터로 받는 값이 없으면 기본값 리턴
// 부모의 생성자 호출
super(msg);
// 부모 멤버변수 변환
super.name = "BadRequestException";
// 자식클래스에서 멤버변수 추가
this._statusCode = 400;
}
// gettter로 statusCode 값 반환
get statusCode() {
return this._statusCode;
}
};
// 모듈 생성
module.exports = BadRequestException;
- Error 클래스를 상속받아 확장된 자식클래스를 모듈을 통해 호출하여 입력값을 검사할 클래스를 만든다.
// 자식클래스 모듈 호출
const BadRequestException = require("./ex_BadRequestException");
// 검사할 클래스 생성
class RegexHelper {
// 메서드 생성
// 파라미터로 받는 input 값은 test 파라미터로, msg 값은 BadRequestException 파라미터로 보낸다.
kor(input, msg) {
// 정규표현식 체크하는 변수 생성(영문+한글)
const check = /^[a-zA-Zㄱ-ㅎ가-힣]*$/;
// .test()를 통해 검사, 파라미터로 받은 값이 정규표현식이 아니라면 강제로 에러 발생
if(!check.test(input)) {
throw new BadRequestException(msg); // BadRequestException 객체 생성
}
}
}
// 모듈 생성
module.exports = RegexHelper;
- try-catch문으로 입력값을 검사한다.
- 입력값이 true면 catch 구문을 무시하고, 입력값이 잘못되면 catch 구문 실행한다.
// 검사하는 클래스 모듈 호출
const RegexHelper = require("./ex_RegexHelper");
// 사용자가 입력한 값
const username = "Java스크립트123"; // 잘못된 값 입력
// 입력값 검사를 수행하기 위한 객체 생성
const regex = new RegexHelper();
try {
// RegexHelper 클래스의 kor() 메서드에 파라미터 값 전달
regex.kor(username, "영문과 한글만 입력하세요.")
} catch(err) {
console.error("%s 에러 발생", err.name); // BadRequestException 에러 발생
console.error("에러코드: %d", err.statusCode); // 에러코드: 400
console.error("에러내용: %s", err.message); // 에러내용: 영문과 한글만 입력하세요.
} finally {
console.log("검사완료");
}
7. 비동기 예외처리
- try-catch는 동기 방식으로 동작하기 때문에 비동기 방식으로 동작하는 코드에는 대응하지 못한다. (timer, ajax 등등)
- 콜백함수를 받아 처리하는 setTimeout( )의 경우, try-catch는 콜백함수 안까지 관여하지 못한다.
const example = [1,2,3];
try {
setTimeout(() => {
// 콜백함수 안까지는 try-catch가 관여하지 못한다.
for(let i = 0; i < 10; i ++) {
console.log(example[i].toFixed(2));
}
// 위에서 에러가 발생했기 때문에 실행되지 않는다.
console.log("배열탐색 종료");
}, 1000) // 1초 뒤 실행되다가 에러가 나는 부분부터 중지된다.
} catch(err) {
// catch 구문도 비동기 함수는 처리하지 못하기 때문에 실행되지 않는다.
console.log("에러발생");
}
// 가장 먼저 실행된다.
console.log("프로그램 종료");
- 비동기 방식을 예외처리 하기 위해서는 콜백함수 내부에서 처리해야한다. (try-catch 문을 넣어야 한다.)
const example = [1,2,3];
setTimeout(() => {
// 콜백함수 내부에 try-catch 선언
try {
for(let i = 0; i < 10; i++) {
console.log(example[i].toFixed(2));
}
// 위에서 에러가 발생했기 때문에 실행되지 않는다.
console.log("배열탐색 종료");
} catch(err) {
// try 구문에서 에러가 발생했기 때문에 catch 구문 실행
console.log("에러발생"); // 에러발생
console.error(err.name); // TypeError
console.error(err.message); // 에러 메세지 내용
}
// 콜백함수 내부에서 처리된 예외처리는 발생한 에러 상황을 처리할 수 있기 때문에 아래의 코드는 정상적으로 실행
console.log("배열탐색 종료2");
}, 1000);
// 가장 먼저 실행된다.
console.log("프로그램 종료");
'국비수업 > JavaScript' 카테고리의 다른 글
[Javascript] DOM의 기본구조 (0) | 2022.03.23 |
---|---|
[Javascript] 비동기처리 (0) | 2022.02.17 |
[Javascript] [연습문제] 내장 기능을 활용한 실습 (0) | 2022.02.16 |
[Javascript] 자바스크립트 내장 기능(Math, Date, Number, Array) (0) | 2022.02.15 |
[Javascript] 모듈 / 자바스크립트 내장 기능(형변환, 이스케핑, 비동기, String) (0) | 2022.02.12 |