본문 바로가기

카테고리 없음

에러 처리

반갑습니다. FoxMon 이에요. 도대체 닉네임이 왜 FoxMon 이냐구요? 글쎄요.. 어디서부터 설명을 드려야 할지.. 제가 귀여운 캐릭터 같은 것들을 굉장히 좋아하는데요. 물론 집에 가지고 있는 캐릭터라곤 라이언과 춘식이 이정도 이지만요..

아무튼 귀여운 캐릭터 중에서 제가 디지몬, 포켓몬 같은 것들을 어릴 때부터 꽤나 좋아했었어요. 거기서의 몬(Mon)과 귀여운 여우(Fox)를 합친 거랍니다. 그래서 FoxMon 이라는 닉네임을 가지게 됐어요.

포켓몬, 디지몬 이야기하는데 갑자기 왜 여우가 나왔냐구요?

.. .. ..

서론이 길었네요. 본론으로 들어가 볼게요.




에러

프로그래밍을 공부하고 계시거나 혹은 취미로 제 글을 읽고 계시는 여러분. 혹시 에러 없는 프로그램을 보신 경험이 있으신가요?
사실 전 없습니다. 게임을 하든, 혹은 단순 앱을 사용하든, 어떤 특정 플랫폼을 사용하든, 항상 에러는 존재하기 마련입니다. 사실 그 시스템을 사용하는 사용자 입장에서는 에러가 났다 한들, 모르고 지나쳤을 수도 있어요. 개발자 입장에서는 이렇게 사용자가 눈치채지 못하게 에러를 처리하고, 그 시스템의 서버에는 에러를 기록해 두거나, 특정 플랫폼으로 알람을 가게 하는 것이 굉장히 중요하고 어려운 일이기도 하거든요.

그만큼 개발자는 에러에 민감합니다. 사용자는 에러가 나서 어떤 오류 페이지를 마주하게 된다거나, 이용하고자 하는 서비스를 사용하지 못하게 되면 굉장히 화가 나거든요. 사실 제일 좋은 것은 에러가 나도 너그러이 이해해주는 사용자만 있다면 문제 없겠지만요.

억지 부리지 말라구요? 알겠어요. 안부릴게요.

아무튼 앞서 말씀드렸듯이 에러처리는 굉장히 중요합니다. 하지만 간혹 개발을 하다 보면 습관적으로 에러 처리를 위한 구문을 작성하고는 합니다. 아래처럼요.

// ...

try {
    doCall();
} catch(error) {
    // ...
}

// ...

하지만 어떻게 에러를 처리해야 할지 몰라 저 catch 구문에 아무것도 작성 안해놓는 경우도 있어요. 이러한 코드를 맞닥뜨리는 당사자는 얼마나 당혹스럽고 억울할지 모르겠네요.

경험담 이냐구요? 네.

그럼 어떻게 에러를 올바르게 처리해야 하며 어떠한 로직에서 어떻게 처리를 해야 할까요?

보통 에러처리는 서버에 특정 요청을 보내거나, 서버라면 데이터베이스에 데이터를 요청하거나 혹은 삽입과도 같은 아주 민감한 처리를 할 때 주로 되곤 합니다. 그 외에도 외부 API와 통신 과정에서도 필요한 부분이기도 하구요.

사실 서버를 왔다갔다 하는 과정에서는 예측할 수 없는 에러가 발생하는 경우가 굉장히 많아요. 예를들자면 한 회사에서 사용하고 있는 웹서버 점검시, 그 찰나의 순간에 서버 요청을 하는 경우 예외가 발생할 수 있어요. 없을듯 해보이지만 실제로 자주 있는 일입니다. 그 특정 시간에 사용자가 사용하지 말란 법은 없으니까요.

그럼 이러한 경우에는 어떻게 예외 처리를 해야 할까요?

공부하고 계신 학생분들 입장에서는 이러한 경우가 낯설기만 할텐데요. 사실 이렇듯 사용자가 특정 액션 없이 코드에서 알아서 에러를 해결할 수 있도록 작성할 수 있답니다.

예시로 한 번 살펴 볼까요?

// ...
let retryFlag = true;

async function getUserList() {
      try {
        await axios.get('/api/v2/foxmons', {
              headers: {
                'Content-Type': 'application/json',
            },
        });
    } catch(e) {
          console.error(e);

        if(retryFlag) {
            await axios.get('/api/v2/foxmons', {
                headers: {
                    'Content-Type': 'application/json',
                },
            });
        }

          retryFlag = false;
    }
}

위의 예시는 단순히 폭스몬들을 불러오는 api를 호출하는 과정을 담고 있습니다. 예외가 발생했을 경우 Flag 값이 참인 경우 재요청 하도록 하고 있어요. 사실 실제로는 이렇게 단순하게 끝날 일은 아닙니다만, 무책임하게 console.error 하나만 남겨서는 안됩니다. 무언가 조치가 필요한 상황이기도 하구요.

더 나아가서 단순힌 Flag의 값에 의존하는 것만이 아닌 몇차례 재요청 하도록 할 수 있는 액션이 필요하기도 하답니다. 그리고 때에 따라서는 특정 플랫폼에 알림이 갈 수 있도록 처리하는 것도 중요하구요. 서버가 갑작스레 꺼지거나 하면 조치를 취할 수 있도록 하는 무언가가 필요하기도 하고, 어디에서 어떤 에러가 났는지 기록을 남길 필요가 있습니다.

이러한 로그를 남겨 놓아야 분석을 할 수 있고 대응을 할 수 있거든요. 에러가 났을 때 로그를 남김으로써 얼마나 큰 안심이 되는지 몰라요. 그렇기에 다양한 상황에 다양한 에러를 핸들링 함으로써 서비스가 안정기에 접어들 수 있다고 생각해요.




결론

처음부터 예외 상황이 없는 정상적인 서비스를 만들 수 있다면 좋겠지만, 사실 전 그것은 불가능에 가깝다고 생각해요. 저희가 사용하는 모든 시스템은 전부 사람이 만든 것이니까요. 완벽한 것은 없다고 생각합니다.

그래서 저는 정상적인 루트로 사용했을 때만 동작하는 시스템에 큰 매력을 느끼지 못합니다. 아무리 열심히 만들었다 한들 배포만 했다 하면 장애가 나거든요.

그렇기에 다양하고 폭넓게 바라보며 에러와 직면하는 것이 중요하다고 생각해요.

그러니 여러분도 에러에 console.error 이것만 남겨놓지 말고 해결하기 위해 적극적으로 트러블 슈팅 해보시면 좋을 것 같아요.

그럼 오늘은 여기까지만 할게요!