개발자를 희망하는 초보의 자기개발 이야기

클린코드 Assignment #10 : 오류처리 본문

도서/클린코드(Clean Code)

클린코드 Assignment #10 : 오류처리

클라우드아실 2024. 12. 11. 02:39
반응형

 

💡TIL (Today I Learned)

2024.12.10

📖 오늘 읽은 범위

7장. 오류처리

✔ 책에서 기억하고 싶은 내용

  • 오류코드보다 예외를 사용하라
    • 오류 처리를 반환값 대신 예외로 처리하는 것이 더 좋다. (중첩에 중첩되는 if문 사용X)
    • 예외를 사용하면 정상적인 코드 흐름과 오류 처리가 분리되어 가독성이 좋아진다.
  • 예외에 의미를 제공하라.
    • 예외가 언제 발생하는지 의도를 명확하게 작성하고, 혼란스러운 예외 사용을 피해야 한다.
  • null을 반환하지 마라
    • null을 반환하면 호출하는 쪽에서 null 체크를 해야 하므로 코드가 복잡해진다.
    • 대신 예외를 던지거나, 명시적인 값을 반환하는 것이 좋다.
  • 특별한 경우를 처리하는 클래스 사용
    • null 대신 Null Object 패턴이나 특별한 오류 객체를 사용해 로직을 단순화하라.

✔ 책에서 기억하고 싶은 내용(프론트엔드 적용버전)

  • 반환값 대신 throw를 사용해 예외를 던져라.
// 나쁜 예시
function getUser(id) {
  if (id <= 0) return null; // 잘못된 경우 null 반환
  return { id, name: "User" };
}

const user = getUser(-1);
if (!user) {
  console.log("User not found");
}


// 개선안
function getUser(id) {
  if (id <= 0) {
    throw new Error("Invalid user ID");
  }
  return { id, name: "User" };
}

try {
  const user = getUser(-1);
  console.log(user);
} catch (error) {
  console.error(error.message);
}
  • 에러 처리 코드와 비즈니스 로직을 분리하라.
// 나쁜 예시
try {
  const response = fetch("/api/data");
  const data = response.json();
  console.log(data);
} catch (error) {
  console.error("Failed to load data", error);
}


// 개선안
// 에러 처리 코드
async function safeFetchData(url) {
  try {
    const response = await fetch(url);
    return await response.json();
  } catch (error) {
    console.error("Fetch failed:", error);
    return null;
  }
}

// 비즈니스 로직
async function main() {
  const data = await safeFetchData("/api/data");
  if (data) {
    console.log(data);
  }
}

main();
  • 에러 처리 코드와 비즈니스 로직을 분리하라 - 각 함수의 에러처리 버전
// 공통 API 요청 함수
async function fetchData(url, options = {}) {
  try {
    const response = await fetch(url, options);

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    console.error(`API 호출 실패: ${url}`, error.message);
    throw error; // 개별 try-catch에서 처리 가능
  }
}

// 각각의 API 요청 함수
async function getUser(id) {
  try {
    const user = await fetchData(`/api/users/${id}`);
    console.log("User data:", user);
  } catch (error) {
    console.error("사용자 정보를 불러오지 못했습니다.");
  }
}

async function getPosts() {
  try {
    const posts = await fetchData("/api/posts");
    console.log("Posts:", posts);
  } catch (error) {
    console.error("게시글 목록을 불러오지 못했습니다.");
  }
}

// 실행
getUser(1);
getPosts();
  • null이나 undefined 대신 기본값을 반환해라.
// 나쁜 예시
function getUser(id) {
  if (id <= 0) return null;
  return { id, name: "User" };
}

const user = getUser(-1);
console.log(user ? user.name : "Guest");


// 개선안
function getUser(id) {
  if (id <= 0) return { id: 0, name: "Guest" }; // 기본값 반환
  return { id, name: "User" };
}

const user = getUser(-1);
console.log(user.name); // 항상 안전하게 접근 가능
  • 의미 있는 에러 메시지를 작성해라.
// 나쁜 예시
throw new Error("Something went wrong");


// 개선안
function getUser(id) {
  if (id <= 0) {
    throw new Error(`Invalid ID: ${id}. ID must be greater than 0.`);
  }
  return { id, name: "User" };
}

try {
  getUser(-1);
} catch (error) {
  console.error(error.message);
}
  • 에러를 개발자용 로그와 사용자 메시지로 나눠 처리하라.
async function fetchData() {
  try {
    const response = await fetch("/api/data");
    if (!response.ok) {
      throw new Error("Network response was not ok");
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.error("Error details for developers:", error); // 개발자용 로그
    alert("데이터를 불러오는 중 문제가 발생했습니다. 다시 시도해주세요."); // 사용자 알림
    return null;
  }
}

fetchData();

📝 오늘 읽은 소감은?

이게 무슨 소리야 욕하면서 본 것 같다. 클린코드가 자바 중심의 책이라 자바스크립트를 다루는 나로써는 이해할 수 없는 예시와 지문들 때문에 책은 20분도 안되서 다 읽었지만 관련한 영상이나 자료를 찾는데 3시간 이상을 쏟아부었다. 이게 노마드코더 챌린지가 아니었으면 여기서 읽기를 때려쳤을 듯. 유튜브에서 관련한 영상들을 찾아보니 의견이 분분한 챕터이기도 한 것 같다. GPT와도 열띤 토론을 나눴다. 이에 따라 프론트엔드 버전용을 별도로 기록하게 되었다. 

결국 이 챕터는 코드의 가독성, 오류 상황에서 시스템의 안정적인 동작 등에 따라 취사선택을 해야할 것 같고, 실무 경험을 쌓아야 논할 수 있을 것 같다.

🤔 궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.

  • Checked Exception  : 컴파일 타임에 예외 처리를 강제하는 자바의 예외 처리 방식이다. 파일 입출력 시 발생할 수 있는 예외( IOException)나  데이터베이스 관련 작업에서 발생할 수 있는 예외(SQLException) 등은 try-catch로 반드시 처리해야 컴파일이 가능하다. 하지만 자바스크립트는 모든 예외가 선택적 처리가 가능한 Unchecked Exception처럼 동작한다.

🔎 참고자료

반응형