프로그래밍Go 개발자

Go에서 오류 처리(에러) 작업은 어떻게 이루어지며, 어떤 접근 방식이 있으며, 오류를 던지는 대신 반환하는 것이 일반적인 이유와 사용자 정의 오류 유형을 구현하는 방법은 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변.

Go에서는 함수에서 error 타입의 값을 반환하는 표준 오류 처리 접근 방식을 사용합니다. 예외를 사용하는 언어와는 달리, Go에서는 예외(panic, recover)가 정말 특별한 상황에서만 사용되며, 비즈니스 로직에는 일반 오류를 사용하는 것이 좋습니다.

고전적인 방법:

func doSomething() error { // ... return nil // 또는 errors.New("some error") } err := doSomething() if err != nil { // 오류 처리 }

더 자세한 분석을 위해 사용자 정의 오류 유형을 만들 수 있습니다:

type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("(%d) %s", e.Code, e.Message) } err := &MyError{404, "not found"}

특정 오류를 확인하는 일반적인 방법:

if myErr, ok := err.(*MyError); ok && myErr.Code == 404 { // 404 오류 처리 }

함정 질문.

Go에서 error를 nil과 ==를 사용해 비교할 수 있나요?

답변: 네, 오류가 없는지 확인하기 위해 비교할 수 있고, 해야 합니다. 그러나 중요한 점은 nil 구조체 내에 nil을 포함하는 오류가 래핑되거나 생성된 경우 비교가 잘못될 수 있습니다. 예를 들어:

var err error = (*MyError)(nil) fmt.Println(err == nil) // false!

인터페이스의 타입이 nil이 아니면 nil이 아닙니다, 내부 값이 nil일지라도요.

주제에 대한 미숙지로 인한 실제 오류 사례.


이야기

마이크로서비스가 nil과의 비교를 통해 오류를 로깅하고 있었습니다. 한 개발자가 타입화된 오류인 (*MyError)(nil)을 반환했는데, 이는 nil과 동등하지 않다는 것을 알아차리지 못했습니다(인터페이스가 nil이 아님). 이로 인해 오류 처리가 중단되었고, 많은 잘못된 경고가 메트릭에 나타났습니다.


이야기

프로젝트에서는 오류를 체인으로 전달하는 대신 모든 오류에 대해 panic을 사용하여 "깨끗한" 방법이라고 생각했습니다. 이는 사용자 입력의 유효성이 없을 경우 애플리케이션이 중단되는 결과를 초래했습니다. panic/recover는 스트리밍 비즈니스 로직을 위해 설계된 것이 아니기 때문입니다.


이야기

오류가 fmt.Errorf("some: %w", err)를 통해 여러 번 래핑되었고, 특정 오류 유형을 확인할 때 일반적인 비교를 사용했습니다. 대신 errors.Iserrors.As를 사용해야 했습니다. 이는 실제로 래핑된 오류 내부에 존재하는 사용자 정의 오류 유형에 대해 비즈니스 로직이 반응하지 않게 만들었습니다.