Firebase Functions와 Slack Webhook을 활용한 에러 알림 시스템 구축 - clappingmin/asterum_traveler GitHub Wiki
문서 목적
이 문서는 Firebase Functions와 Slack Webhook을 활용하여 구축한 에러 알림 시스템의 배경, 구조, 구현 방식, 문제점과 개선 방향을 정리한 기록이다. 해당 시스템은 1인 개발 환경에서 운영 중 발생하는 예외 상황에 빠르게 대응하기 위한 경량화된 실시간 에러 모니터링 도구로 사용된다.
도입 배경 및 목표
이 프로젝트는 PLAVE 아카이브 페이지로서 장기간 유지보수될 예정이며, 운영 안정성이 중요하다. 그러나 1인 개발자로서 사용자 레벨에서 다양한 테스트를 수행하는 것이 현실적으로 어렵다. 다음과 같은 한계가 있었다:
- 개발자 본인이 배포 후 테스트를 진행해도 테스트 케이스가 제한적일 수밖에 없음
- 유닛 테스트로 커버되지 않는 예외 상황이 실서비스에서 발생할 수 있음
- 배포된 웹에서는 사용자에게 에러 메시지를 노출하지 않도록 설계되어 있음
따라서 예상치 못한 에러를 개발자가 실시간으로 인지하고 대응할 수 있도록, 에러 발생 시 Slack으로 메시지를 전송하는 구조를 구축했다.
Firebase Functions를 선택한 이유
- 이미 Firebase Database를 사용 중이었기 때문에, 동일 콘솔에서 에러 알림도 관리하는 것이 편리
- 서버를 별도로 구축하고 싶지 않아 서버리스 구조 유지가 필요
- Slack Webhook은 간단한 HTTP POST만으로 알림이 가능하므로 Firebase Functions의 HTTP 트리거와 궁합이 좋음
에러 핸들링 구조
- 공통 에러 타입인
ApiError
클래스를 정의 - 서비스 로직에서 예외 발생 시, 해당 에러를
throw new ApiError(...)
방식으로 명시적으로 발생시킴 - API를 호출하는 컴포넌트에서는
FetchErrorBoundary
로 감싸 에러를 분리 처리 - 전체 애플리케이션 루트는
GlobalErrorBoundary
로 감싸 클라이언트 레벨에서 잡히지 않은 오류를 캐치
구현 방식 요약
- Firebase Functions의 HTTP 트리거 엔드포인트(
/errorLog
)를 생성 - 클라이언트/서버 코드에서 에러 발생 시 해당 API에 JSON 형태로 POST 요청
- Functions는 해당 에러를 Slack Webhook으로 전송
현재 문제점 및 개선 방향
1. SSR 환경에서 GlobalErrorBoundary 누락
vite-plugin-ssr 마이그레이션 과정에서 GlobalErrorBoundary
가 루트 컴포넌트에서 누락된 상태이며, 클라이언트에서 발생하는 일부 오류가 감지되지 않음
개선 방향: SSR과 CSR이 혼합된 구조에서도 루트 컴포넌트에 반드시 GlobalErrorBoundary
를 포함해야 함
2. React Query 에러 구분 불가 문제
서비스 내부에서 발생한 ApiError
는 명시적으로 처리되지만, react-query
내부에서 발생하는 에러는 Error
인스턴스일 뿐 ApiError
가 아니기 때문에 구분이 되지 않음
개선 방향:
react-query
의 훅에서 에러를 잡아ApiError
로 변환하는 커스텀 훅 작성- 혹은
error
를 분석해 타입 판별 후 Slack에 전송하는 포맷을 분기 처리
3. SSR의 404 처리 누락
현재 SSR 구조에서는 잘못된 라우트 요청 시 커스텀 404 페이지 대신 내부 서버 오류가 발생함
개선 방향:
- SSR의 HTML 렌더링 (
escapeInject
) 부분을try-catch
로 감싸고, 404
또는 기타 오류 발생 시 커스텀 에러 페이지를 클라이언트에 전달하도록 수정
정리
1인 개발 환경에서 다양한 유저 시나리오를 사전에 테스트하기 어렵기 때문에, Slack 기반 에러 알림 시스템은 운영 안정성과 신속한 대응에 필수적인 구성 요소이다. Firebase Functions와 Slack Webhook을 활용한 이번 구성은 서버리스 환경에 최적화된 간결하고 유지보수하기 쉬운 에러 모니터링 시스템으로서, 장기 운영을 고려한 구조적인 선택이었다.