본문 바로가기
Golang/Tucker

[묘공단] 5주차 (1)

by 윤원용 2023. 10. 29.

이 글은 골든래빗 《Tucker의 Go 언어 프로그래밍》의 23장 써머리입니다.

 

23장은 error와 관련된 내용들을 소개하고 있다. 어떤 프로그래밍언어든 error처리는 중요하니 책에 나온 내용과 간단한 예제를 추가해 리뷰할 예정이다.

 

더보기
  • 23 에러 핸들링
    • 23.1 에러 반환
    • 23.2 에러 타입
    • 23.3 패닉

 

23.1 에러 반환

책에서는 두 가지 형태의 예제로 에러 처리에 대해 설명하고 있는데 첫 번째는 file 관련된 내장 라이브러리들의 함수를 호출하면서 발생하는 에러를 처리하는 방식이고 두 번째는 개발자의 코드에서 목적에 맞게 에러처리하는 예제로 설명한다.

에러를 반환한다는 뜻은 크게 세 가지의 이점이 있는데 

1. 프로그래머가 예상하지 못해 발생한 에러나 외부 라이브러리를 사용 시 발생한 에러를 로깅해 추후에 빠르게 보안할 수 있음

2. 버그 발생 시 프로그램이 종료되지 않고 계속 실행함 (선택적으로 죽이기도 함)

3. 프로그래머끼리 협업할 때 단위테스트가 없는 경우 에러가 발생해도 반환된 에러로 추적하기 쉬움

사실 1번과 3번은 프로그램을 개발한 개발자가 에러 메시지를 잘 만들어서 반환해야 의미가 있다.

본인은 그나마 실무에서 사용할만한 예제를 공유하고 싶어 redis라는 in-memory db를 외부 라이브러리를 사용해 connection pool을 만들고 에러처리하는 예제를 만들어 보겠다.
외부 라이브러리는 redigo를 사용할 것이고 공유한 링크를 클릭하면 설치 방법도 다 나와있어 좋다.

KISS 원칙을 따라 쉽고 간결하게 만들어보도록 하자!

막상 코딩하고 보니 너무 양이 많아서... 에러처리하는 곳만 살펴보겠다. ㅠㅠ;;

예제 코드 폴더 구조

위 이미지는 예제 코드 폴더 구조이며, redis 폴더의 package는 module_cache다.

앞서 설명한 첫 번째 방법처럼 함수를 호출한 후 error type의 결과를 받아 처리하는 예제로 main 파일부터 살펴보면

redisPoolInit 함수의 반환형은 error type인 것을 볼 수 있고 main 함수에서 redisPoolInit 함수를 호출하는 부분을 어떻게 하냐인데 이런 것을 error handling이라 한다.

두 번째 방법으로 프로그래머가 생각한 에러 상황에 에러를 만들어 error handling 하는 방법이다.

위 코드를 설명하면 redis connection pool를 만들어 pool에서 conn을 하나씩 꺼내면서 추후에 close 하기 위해 connList에 push 한 후 ping 테스트를 한다. ping을 날린 후 결과가 error인 경우 에러 메시지를 개발자가 더 알기 쉽게 만들고 반복문을 멈춘다. initClean함수를 통해 생성한 conn 객체를 close 한다.

initClean함수에서도 conn 객체를 close 할 때 발생한 에러를 개발자가 알기 쉽도록 에러 메시지를 변경한다.

책에서는 내장 라이브러리인 errors package를 사용해 error를 다루는 다른 방식을 알려주지만 본인은 fmt.Errorf나 github.com/pkg/errors package의 errors를 사용하는 게 편한 것 같다. 보통은 함수를 호출한 후 발생한 에러에 내용을 추가하는 식으로 많이 하지만 에러가 발생하지 않을 상황에서도 개발자가 에러를 발생시킬 경우도 있고 에러가 발생한 callstack도 같이 보고 싶을 때가 있기 때문이다. callstack를 볼 때 많은 도움을 주는 pkg/errors package 사용하면 좋다.

 

23.2 에러 타입

본인은 이것을 사용해 본 경험이 거의 없다. 앞서 설명한 redis에 저장한 내용이 없어 nil이 나올 경우 redis.ErrNil로 타입을 확인할 수 있지만 이것 조차 사용하지 않기 때문에 필요성을 잘 모르겠어 pass...
     우리에겐 만능 %#+v 포맷이 있기 때문!!!

 

23.3 패닉

본인처럼 JAVA나 JS를 좋아하는 개발자들은 Golang을 하면서 error handling이 너무 짜증 나고 귀찮은 경험을 했을 것 같다. 이럴 때 Golang에서 try catch 같은 것이 있는지 찾을 때 자주 나오는 게 panic과 recover다. 하지만 try catch처럼 panic과 recover를 쓰는 것은 그다지 좋지 않은 방법인 것 같다. 책에서는 panic을 이렇게 설명하는데

프로그램을 정상 진행하기 어려운 상황을 만났을 때

라고 한다. 간단한 예제를 통해 이해해 보자.

앞서 사용했던 예제에서 main 함수만 수정한 코드이다. panic을 성명하기 앞서 간단한 전제를 두면 웹 서버를 코딩한다 생각해 보자. 사용자들의 정보를 저장하기 위해 필요한 db를 초기화하지 못한 상태에서 웹 서버를 띄우면 어떻게 될까? 

당연히 웹 서버를 띄운 의미가 없을 것이다. 이렇듯 프로그램을 정상 진행하기 어려울 때 panic을 사용하는 것이다.

recover는 panic이 발생했을 때 catch 해주는 역할을 하고 panic 함수 호출 시 파라미터로 넣은 내용을 반환한다. 꼭 필요하진 않지만 panic이 발생한 경우는 큰 문제임으로 recover가 있는 defer에 다른 사람들과 공유할 수 있는 메신저를 통해 알리는 로직을 개발하는 것이 좋다.

 

23장은 이것으로 마치겠다.

 

'Golang > Tucker' 카테고리의 다른 글

[묘공단] 5주차 (3)  (0) 2023.10.29
[묘공단] 5주차 (2)  (0) 2023.10.29
[묘공단] 4주차  (2) 2023.10.22
[묘공단] 3주차 (2)  (1) 2023.10.16
[묘공단] 3주차 (1)  (2) 2023.10.15