예외처리란?( + 적용)

성찬홍·2023년 8월 6일
0

Code Refactoring

목록 보기
4/5

1. 예외처리란?

  • 코드 실행 중에 예기치 못한 에러가 발생했을 때, 이로부터 코드의 실행 흐름을 복구할 수 있는데, 이를 예외처리(Excpetion handling) 라고 한다.

  • JavaScript는 기본적으로 싱글 스레드라서 스레드가 멈춘다는 것은 프로세스가 멈추는 것이라서, 예외처리는 필수이다.

2. JavaScript의 예외처리 방법

& try catch finally
try ... catch .. finally 구문을 사용하여 에러가 나더라도 코드의 실행을 지속할 수 있다.

ex) try catch

try {
  console.log('에러가 나기 직전까지의 코드는 잘 실행됩니다.');
  new Array(-1); // RangeError: Invalid array length
  console.log('에러가 난 이후의 코드는 실행되지 않습니다.');
} catch (e) {
  console.log('코드의 실행 흐름이 catch 블록으로 옮겨집니다.');
  alert(`다음과 같은 에러가 발생했습니다: ${e.name}: ${e.message}`);
}

→ 에러가 났을 때 원상 복구를 시도할 때, try블록 내부에 작성하면, 에러가 발생했을 때 코드의 실행 흐름이 try 블록에서 catch 블록으로 옮겨간다. 이 때, catch 블록 안에서는 에러에 대한 정보를 담고 있는 객체 e를 사용할 수 있다.

ex) try finally

for (let i of [1, 2, 3]) {
  try {
    if (i === 3) {
      break;
    }
  } finally {
    console.log(`현재 i의 값: ${i}`);
  }
}

finally 블록이 사용되면, try 블록 안에서의 에러 발생 여부와 관계없이 무조건 실행된다.
→ finally 블록은 catch 블록과도 사용된다.
→ 에러가 안 났을 때 : try-finally
→ 에러가 났을 때 : try - 에러 발생 - catch -finally

ex) Error 생성자 throw ( 에러 직접 발생시키기 )

const even = parseInt(prompt('짝수를 입력하세요'));
if (even % 2 !== 0) {
  throw new Error('짝수가 아닙니다.');
}

→ 에러의 종류를 구분해야하거나 에러 객체에 기능을 추가해야할 필요가 있을 때 사용한다.

ex) 비동기 코드에서의 에러

(1) Promise 의 경우

Promise.resolve()
  .then(() => {
    throw new Error('catch 메소드를 통해 예외 처리를 할 수 있습니다.');
  })
  .then(() => {
    console.log('이 코드는 실행되지 않습니다.');
  })
  .catch(e => {
    return e.message;
  })
  .then(console.log);

→ 기존 try catch 블럭에 넣을 경우에는 try 블록을 비동기 함수가 만날 수 없다.
→ 그래서,비동기 위와 같이 비동기 콜백의 내부에 try 블록을 작성해줘야 한다.
→ then 메소드의 연쇄 안에서 에러가 발생하면, try...catch 구문과 유사하게 처음 만나는 에러 처리 콜백으로 코드의 실행 흐름이 건너뛰는 결과를 넣게 된다.

(2) async await 사용의 경우

async function func(){
	try{
		const res = await fetch("https://~~");
	}
		catch(e){
		console.log(e.message);
	}
}
func(); //Failed to fetch

→ async await 형태를 사용하면, 위의 체인 형태의 복잡한 구조를 좀 더 단순하게 만들어줄 수 있다.


3. 내 코드에서의 적용

프르젝트를 진행하면서 , 백엔드에서 MYSQL 연동관련 api 호출을 할 때, 요청 파라메타가 전달이 되지 않는 오류를 가장 많이 받았었습니다.
그래서 이 부분에 대해서 에러처리를 해 볼 예정입니다.

(1) 기존 코드

mysql connection 객체로 쿼리 실행 시에 , 에러 발생하면 error를 throw하는 형태이며,
SQLdata에 값이 제대로 들어오지 않았을 때 , error가 발생하고 서버가 중단됩니다.

getClubDetailInfo: async (req, res) => {
    const selectSQL = `SELECT * FROM CLUB_TABLE WHERE C_IDX =?`;
    const SQLdata = [req.query.data];

	connection.query(seletSQL, SQLData, (error, result) => {
      if (error) throw error;
      res.status(200).send(result);
    });

  }

(2) 수정 후 코드

아래처럼 수정을 한 후로,SQLdata 문제가 생기더라도 , 서버는 끊기지 않으며, 상태 코드로 현재문제만 전달받을 수 있게 되었습니다.
이 외의 api 코드도 대부분 수정전 코드와 같이 구성되어있어서, 아래와 같이 수정을 하였습니다.

getClubDetailInfo: async (req, res) => {
    const selectSQL = `SELECT * FROM CLUB_TABLE WHERE C_IDX =?`;
    const SQLdata = [req.query.data];

    try {
      // 기존 SQLdata 문제를 null,undefined 체크를 미리 해주어,
      // 문제 발생 시에  TypeError를 던져주고 아래 실행문은 실행되지 않고, catch문으로 넘어가고 상태 코드 405 를 클라이언트로 전달해준다.
      if (req.query.data === null || req.query.data === undefined)
        throw TypeError("SQLdata Null Error");
      connection.query(selectSQL, SQLdata, (error, result) => {
        if (error) throw error;
        res.status(200).send(result);
      });
    } catch (error) {
      if (error instanceof TypeError) {
        res.status(405).send("SQL Error");
      } else {
        res.status(406).send("Error :" + error);
      }
    }
  }

4. 느낀점

사이트를 만들면서, try catch 구문이 예외처리문이라는 정도는 알고 있었지만, 제대로 된 처리를 안해 둔 상태였습니다.

이번에 적용을 하면서 가장 많이받았던 오류를 떠올려 처리를 해주었는데, 아직 제가 생각하지 못한 예외처리부분들이 많을 것 같습니다.
좀 더 처리해야될 부분이 생기면 바로바로 업데이트해나가야겠다는 생각이 들었습니다.

https://helloworldjavascript.net/pages/290-exception.html
https://www.youtube.com/watch?v=EBmIHrLTVdg&ab_channel=코드종

profile
꾸준한 개발자

1개의 댓글

comment-user-thumbnail
2023년 8월 6일

많은 것을 배웠습니다, 감사합니다.

답글 달기