
- #etc
프론트엔드에서의 에러와 예외
Prolip
2025-03-11
팀 프로젝트에 앞서 프론트엔드에서의 에러와 예외가 무엇이고 어떻게 처리할지 잠시 고민해보기..
시작하며..
이번에 팀 프로젝트를 진행하기에 앞서 효율적이고 사용자 경험 측면에서 유리한 에러 처리를 어떻게 달성할까에 대해 많은 고민을 하게 되었는데요.
먼저 제가 달성한 에러 처리 전략을 소개하기에 앞서 프론트엔드에서의 에러와 예외 처리란 무엇인지에 대해 정리해보려고 합니다.
프론트엔드에서의 에러와 예외 처리
개발을 할 때 ‘누가 봐도 끌리는 디자인’, ‘빠른 속도’, ‘평범하지 않은 기능’ 등이 중요한 것은 사실입니다. 하지만 서비스의 완성도를 높이기 위해서 에러 핸들링 또한 필수적이라고 생각하는데요.
사용자 경험과 서비스 신뢰도를 결정짓는 중요한 요소 중 하나라고 생각하기 때문입니다. 사용자는 오류가 발생하더라도 명확하게 안내를 받고, 서비스가 즉시 복구되거나 혹은 대체 방안을 제공받기를 기대하기 때문이에요.
에러 헨들링이 제대로 이루어지지 않으면, 사용자는 당황하거나 서비스 이용을 포기하고 이탈할 가능성이 높아져요. 따라서 신뢰할 수 있는 서비스를 만들기 위해서 에러 핸들링을 철저하게 고려해야 된다고 생각합니다.
에러와 예외?
에러
먼저 에러는 프로그램이 실행되는 동안 예상치 못한 상황이 발생해 정상적인 동작을 방해하는 현상을 의미해요. 보통 코드의 문법적 오류나 논리적 오류로 인해 발생하는데요.
개발 도중 잘못된 코드를 작성했을 때 브라우저에 나타나는 Syntax Error (예를 들면, const foo = ;), 코드가 실행되는 도중 발생하는 Runtime Error (예를 들면, null 값을 참조하는 경우), 혹은 코드가 실행은 되지만 기대하지 않은 결과가 나오는 Logic Error가 있어요.
예외
예외는 런타임 환경(배포 후라고 볼 수 있겠죠?)에서 발생할 수 있는 특별한 상황으로, 프로그램이 예측할 수 있는 범위 내에서 적절히 처리할 수 있는 오류를 의미해요. 하지만 예외 처리를 적절히 하지 않으면 프로그램이 죽을 수 있어요. (종료돼요.)
- 클라이언트 측 예외: 사용자의 잘못된 입력, 네트워크 문제, API 응답 실패 등이 있어요.
- 서버 측 예외: 서버가 부하를 이기지 못하고 다운된다거나, DB 연결 오류, 권한 부족 등이 있어요.
- JS 내장 예외: 타입 에러, 레퍼런스 에러, 구문 에러 등이 있어요.
예측 가능한 에러 vs 예측 불가능한 에러
예측 가능한 예러 (Handled Errors)
예측 가능한 에러는 개발자가 미리 예상하고 대비할 수 있는 에러로 적절한 예외 처리를 통해 프로그램이 중단되지 않도록 조치할 수 있어요.
- 사용자가 잘못된 형식의 데이터를 입력하는 경우가 있어요. string 타입의 데이터를 입력 받길 기대했으나 number 타입의 데이터를 입력하는 경우는 개발자가 미리 예측할 수 있어요.
- 서버가 불안정해 응답이 지연되거나 혹은 실패한 경우는 미리 예측하고 대비할 수 있어요.
- 로그인하지 않은 사용자가 보호된 페이지에 접근하는 경우도 미리 예측할 수 있어요.
- 입력 폼의 경우 필수 값이 누락되는 상황도 예측이 가능해요.
예측 불가능한 예러 (Unhandled Errors)
- 서버가 다운되거나 데이터베이스 연결이 끊어진 경우
- 특정 브라우저에서만 발생하는 예상치 못한 버그
- 사용자의 환경 이슈로 인한 네트워크 연결 문제 혹은 디바이스 성능 문제
위와 같은 상황은 예상할 수 없는 환경적 요인 혹은 외부 시스템의 문제로 발생하는 경우로 예측이 불가능하기 때문에 적절한 로깅과 복구 전략이 필요해요.
그럼 어떻게 처리할까요?
먼저 에러를 처리하는 과정에 앞서 중요한 요소를 먼저 소개하겠습니다.
1. 사용자 친화적인 에러 메세지를 제공해요.
개발자용 콘솔 로그가 아닌, 사용자가 이해할 수 있는 에러 메세지를 제공해야 합니다.
예를 들어, 500 Internal Server Error 대신 서버에 문제가 발생했어요. 잠시 후 다시 시도해주세요. 와 같은 메세지를 제공하는 것이 좋을 거 같아요.
2. 적절한 피드백 제공
사용자에게 오류가 발생했다는 정보를 즉시 제공해 혼란을 줄여야 해요.
예를 들어, toast
를 통해 에러 메세지를 짧게 전달하거나, 혹은 ErrorBoundary
를 활용해 화면 내에서 대체 UI를 제공할 수 있습니다.
예측 가능한 에러 처리
먼저 위에서 살펴본 예측 가능한 에러의 경우를 살펴봅시다.
1. 폼 입력 유효성 검사
사용자가 올바른 형식으로 데이터를 입력하도록 유도할 수 있어요. 혹은 필수 입력 필드가 비어있을 경우 즉시 피드백을 제공할 수 있어요.
const rules = { address: [(value) => (!value ? "주소지를 입력해주세요." : "")], contact: [ (value) => (!value ? "전화번호를 입력해주세요." : ""), (value) => { const regExp = new RegExp(/^\d{2,3}-\d{3,4}-\d{4}$/u); if (!regExp.test(value)) { return "전화번호 형식으로 입력해주세요. (예: 010-1234-5678)"; } else { return ""; } }, ], }; class Validation { constructor(rules) { this.rules = rules; } validateField(name, value) { const fieldRules = this.rules[name]; if (!fieldRules) return ""; for (const rule of fieldRules) { const errorMessage = rule(value); if (errorMessage) return errorMessage; } return ""; } validate(formState) { const errors = {}; for (const name in formState) { errors[name] = this.validateField(name, formState[name]); } return errors; } } const validator = new Validation(rules); const validate = (formState) => { return validator.validate(formState); };
2. 네트워크 요청 실패 처리
응답이 지연되거나 혹은 응답이 실패한 경우 사용자에게 재시도를 유도할 수 있어요.
try { // 데이터 요청 } catch (error) { console.error('데이터를 불러오는 중 오류가 발생했어요.:', error); alert('데이터를 가져올 수 없습니다. 인터넷 연결을 확인하고 다시 시도해주세요.'); }
예측 불가능한 에러 처리
예측이 불가능한 에러는 적절히 예외 처리를 하지 않으면 런타임 환경에서 프로그램이 종료될 가능성이 높아요.
가장 간단한 방법은 window 객체에 이벤트 리스너를 등록할 수도 있어요. 적절한 에러 핸들링 전략이라고는 생각이 들지 않지만, 적어도 프로그램이 종료되는 상황은 해결할 수 있어요.
window.addEventListener('error', (event) => { console.error('전역 오류 발생:', event.message); alert('알 수 없는 오류가 발생했습니다. 새로고침 버튼을 눌러주세요.'); }); window.addEventListener('unhandledrejection', (event) => { console.error('처리되지 않은 Promise 거부:', event.reason); alert('네트워크 연결이 원활하지 않거나, 요청을 처리할 수 없습니다. 잠시 후 다시 시도해주세요.'); });
혹은 Next.js의 경우 폴더 최상단에 error.tsx 파일을 사용해 발생한 에러 버블링의 최상단 지점에서 잡아내는 방법 등 다양한 방법이 존재해요.
혹은 Sentry를 사용해 에러를 로깅해 이후 에러를 예측할 수 있도록 개선하는 방법도 존재해요.
사실상 예측 불가능한 에러의 경우 서버의 문제와 사용자 접속 환경 등의 요인이 크기 때문에 적절히 재시도를 유도하는 대체 UI를 제공하는 방법이 최선이라고 생각합니다.
결론
프론트엔드 개발에서의 에러 핸들링은 단순히 오류를 잡는 과정이 아니라고 생각해요. 사용자가 신뢰할 수 있는 서비스를 만드는 과정이고, 철저한 예외 처리와 친절한 오류 안내는 서비스의 품질을 높이고, 곧 사용자의 만족도를 높여 서비스 이탈률을 낮추는 중요한 요소가 된다고 생각합니다.
따라서 에러 핸들링은 개발 과정에서 필수적으로 고려해야될 사항이라고 생각합니다,
이후에 작성할 문서에서 예측 가능한 에러와 예측 불가능한 에러를 어떻게 효율적으로 처리할 수 있었는지에 대해 기록할 예정입니다..

HTTP - 브라우저의 HTTP 요청
