에러처리
프로그램은 컴퓨터에게 실행할 작업을 지시하고 그 작업을 수행하기 위한 명령어의 집합이며, 일반적으로 사용자의 요구에 따라 원하는 작업을 수행하도록 설계된다. 즉, 사용자의 요구(입력)에 따라 특정 명령어가 실행 되도록 하는 것이 프로그래밍이라고 정의할 수 있다.
만약 사용자들의 입력사항을 완전히 신뢰할 수 있다면 프로그램의 런타임 에러는 획기적으로 줄어들 것이다. 하지만 개발자들은 사용자들을 100% 신뢰할 수 없고 그래서도 안된다. 그러므로 사용자의 입력에 대해서는 유효성 검증, assertion 등 에러를 처리할 수 있는 방법을 강구해야 한다.
만약 사용자 입력에 대해 유효성 검증이나 에러 처리를 하지 않는다면 프로그램 내에서 사용되는 데이터의 일관성과 신뢰성이 무너지게 될 것이고, 이는 프로그래머가 예측하지 못한 상황에서 터지는 런타임 에러의 시발점이 될 것이다.
예측하지 못한 상황에서 에러가 터지는 것은 상당히 괴롭다. 우리는 에러도 우리가 예측한 상황 내에서 터지기를 바란다. 개발자가 신뢰할 수 있고, 예측 가능한 범위 내에서 선제적으로 에러를 내는 것이 에러처리의 기본(?)이 아닐까 싶다.
assert 함수
assert 함수는 프로그래밍에서 주어진 조건이 참(True)인지 확인하기 위해 사용되는 함수이다. 주로 디버깅 목적으로 사용되며, 프로그램의 특정 지점에서 조건이 참인지 확인하고, 만약 조건이 거짓(False)이면 AssertionError 예외를 발생시킨다.
아래의 코드는 페이지에서 받는 특정 Slug가 개발자가 정의한 배열 내에 위치하는지 체크하는 assertion 함수이다.
type CheckSlug = 'cow' | 'horse' | 'dog'
function isCheckSlug(slug: string): slug is CheckSlug {
return ['cow', 'horse', 'dog'].includes(slug)
}
export function assertCheckSlug(slug: string): CheckSlug {
if (!isCheckSlug(slug)) {
throw new Error(`Invalid slug ${slug}`)
}
return slug
}
- assertCheckSlug 함수에 특정 slug를 파라미터로 하여 호출하면 내부적으로 그 slug가 유효한지 체크를 한다.
- 만약 slug가 cow, horse, dog가 아니라면 Assertion Errer 예외를 발생시킨다.
활용(app router, next.js)
위의 assert 함수를 next.js의 app router에서 활용해보자.
참고로 이 assertion 기법은 프론트엔드에서만 사용하는 것은 아니며, 사용해야하는 이유와 동작 원리를 알게 된다면 필요한 곳이 어디든간에 쉽고 빠르게 적용할 수 있을 것이다.
type CheckSlug = 'cow' | 'horse' | 'dog'
type PageData = {
title: string,
sounds: string,
}
const pageData = {
[_key in CheckSlug]: PageData
} = {
cow: {
title: '한우'
sounds: '음메'
},
horse: {
title: '조랑말'
sounds: '히히히힝'
},
dog: {
title: '진돗개'
sounds: '멍멍왈왈'
}
}
async function getPageData(
slug: string,
): Promise<PageData> {
return pageData[assertCheckSlug(slug)]
}
const Page: FunctionComponent<PageProps> = async ({
params: { slug },
}) => {
const pageData = await getCheckIntroPageData(slug)
return (
<main>
<SomeComponent1 {...pageData} />
<SomeComponent2 {...pageData} />
<SomeComponent3 {...pageData} />
</main>
)
}
export default Page
- 위 page 컴포넌트에 따르면 사용자가 입력한 slug에 의해 SomeComponent에 전달되는 props가 달라진다.
- 사용자가 입력할 수 있는 유효한 slug는 cow, horse, dog로 제한된다. 준비된 데이터가 세 개밖에 없기 때문이다.
- 그러므로 사용자가 입력한 slug가 위 세 단어가 아니라면 에러를 내야 한다.
- 하지만 위의 방법을 사용한다면 에러를 낼 수 있는 방법이 마땅치 않다.
- switch-case문으로 모든 케이스에 맞는 데이터를 제공하자니 유지보수가 복잡해질 수 있다.
- 따라서 사용자가 입력한 slug를 데이터 파싱 함수에 전달하기 이전에 assertion 검증을 수행해본다.
- 유효한 slug라면 정상동작할 것이고, 유효하지 않은 slug라면 에러가 발생한다.
- assertion에서 생성된 에러는 에러 처리 페이지를 따로 만들어 처리할 수 있고, 내가 지정한 에러 메세지를 이용하여 사용자에게 에러가 왜 났는지도 알려줄수도 있다..
결론
개발하고 있는 프로그램의 로직이 방대해지고 있음에도 불구하고 에러 처리를 등한시한다면 나중에는 어디에서 에러가 발생했는지 추적이 어려운 상황이 생길 것이다. 런타임 에러를 100% 막을 수 있다면 좋겠지만 아쉽게도 사람이 하는 모든 일에는 실수가 있을 수 있다.
끄래도 개발을 하다보면 어디에서 나는 에러가 치명적인지, 사용자가 어떻게 입력하면 에러가 날 것인지 정도는 우리가 파악할 수 있다. 그러한 부분을 하나 둘 막아가다보면 정말 치명적인 에러는 막을 수 있지 않을까.
사용자 입력도 100% 신뢰할 수 없지만, 내가 처리한 코드도 100% 신뢰하면 안된다. 그러므로 항상 검증하자.
(그래도 돈받고 일하는 프로의 입장으로써 내가 작성한 코드의 한 95% 정도는 신뢰할 수 있도록 노력해보자.)
'개발 일지' 카테고리의 다른 글
프론트엔드 설계 아이데이션 (0) | 2024.01.12 |
---|---|
iOS/Android flutter 웹뷰 렌더링 엔진 이슈 해결 (1) | 2024.01.08 |
기록으로 남기는 docker 명령어 실행 순서 및 명령어 (2) | 2023.12.13 |
문제가 있는 함수 (Date 객체와 불변성) (0) | 2023.12.12 |
나보려고 남기는 pnpm + nextjs 프로젝트 세팅 (1) | 2023.12.05 |