매우 짧은 요약: 오류가 발생하면 프로그램을 종료하는 것이 좋습니다. 고베일을 이용하시면 생활이 더욱 편리해집니다.
Go 코드에 오류가 발생하면 일반적으로 다음과 같은 내용이 표시됩니다.
err := myFunc() if err != nil { return fmt.Errorf("doing my thing: %w", err) }
이 예에서 몇 가지 사항을 확인할 수 있습니다.
그럼 다음은 어떻게 될까요? 글쎄, 모든 일이 다시 일어납니다. 오류 값을 확인하고 설명하고 다시 전달합니다. 그리고 모든 것이 다시 시작됩니다.
우리는 왜 이러는 걸까요? 왜 이렇게 노력하는 걸까요?
글쎄, 그것은 모두 당신이 작성하는 소프트웨어에 달려 있습니다. 오류가 발생하면 결정을 내려야 합니다. 해당 오류는 어떻게 되나요?
요청에 응답하는 HTTP API를 작성하는 경우 결국 일종의 HTTP 핸들러에 도달하게 되고 해당 오류를 일부 응답으로 변환하게 됩니다. 적절하게 또는 아마도 500을 요청하고 애플리케이션의 상태에 대한 걱정스러운 메시지를 보냅니다. 또는 일종의 CLI 도구를 작성하는 경우 오류가 결국 기본 기능으로 다시 전달되도록 결정할 수도 있습니다. 어떤 종류의 프로그램이든 충분하다고 판단할 수 있습니다. 다른 작업을 수행할 수 없으므로 프로그램을 종료해야 합니다.
마지막 옵션을 살펴보겠습니다. 언제 프로그램을 종료하는 것이 적절한가요? 제가 생각할 수 있는 몇 가지 이유는 다음과 같습니다.
아. 더 이상 할 수 있는 일이 없습니다. 오류가 너무 심해서 지금 당장 모든 것을 멈춰야 합니다
비. 프로그램 종료에 따른 결과는 없습니다(정리 필요 없음, 응답할 상태 없음)
기음. 일찍 중지하는 것이 바람직합니다. 아마도 프로세스를 깔끔하게 다시 시작하는 모니터가 있을 것입니다
이유가 무엇이든 어떻게 깔끔하게 퇴장할 것인지 고민해야 합니다. 이제 가장 먼저 시도해 볼 수 있는 것은 다음과 같습니다.
err := myFunc() if err != nil { fmt.Printf("doing my thing: %v", err) os.Exit(1) }
원래 오류 처리 코드와 꽤 유사해 보이지만 몇 가지 중요한 차이점이 있습니다. 첫 번째는 꽤 명백합니다. 경적을 울리는 훌륭한 stop-right-g*****n-now 문이 있습니다. 귀하의 프로그램은 계속되지 않을 것입니다. 두 번째 요점이 아마도 더 중요할 것입니다. 이 샘플을 호출하는 코드는 오류 처리에 대해 걱정하지 않습니다. 테스트해야 할 추가 코드 경로는 없습니다. 확인해야 할 반환된 항목이 없기 때문에 호출 코드에 테스트할 if 블록이 없다고 신뢰할 수 있습니다.
그래서 저는 종료 코드가 제대로 작동할 것이라고 믿어야 한다고 제안했을 때 아마도 약간 열광했을 것입니다. 새 프로그램이 중지된 이유가 올바른지 확인해야 합니다.
이건 쉬울 것 같네요. 고려해야 할 몇 가지 사항은 다음과 같습니다. 가장 쉬운 경우에는 프로그램을 실행하고 오류 조건을 트리거할 것입니다. 예를 들어 CLI 도구를 사용하여 존재하지 않는 파일을 열 수 있습니다. 몇 가지 간단한 경우에는 이 작업을 수동으로 수행할 수 있습니다. 테스트 수가 늘어나면 이를 지원하기 위한 일종의 자동화가 필요할 것입니다.
간단한 참고 사항 - 이것은 아마도 다른 블로그 게시물 전체의 주제일 것입니다. 그러나 제가 현재 가장 선호하는 CLI 도구 테스트 방법은 godog를 사용하여 테스트를 작성하는 것입니다. 약간 복잡할 수 있지만 매우 강력하다는 것을 알았습니다. 다음은 내가 Layli와 Wait-for를 사용하여 어떻게 접근했는지에 대한 좋은 예입니다.
이 접근 방식을 사용하면 훨씬 더 많은 결과를 얻을 수 있지만 때로는 자신감을 갖고 싶은 모든 코드 경로를 적절하게 실행하는 조건을 만드는 것이 어려울 수 있습니다.
좋아, 이제 Go 언어의 일부 기능을 사용해 보겠습니다. 실제로 os.Exit를 호출할 필요는 없습니다. os.Exit와 유사한 것을 호출할 수 있습니다. 그럼 이것을 보세요:
err := myFunc() if err != nil { return fmt.Errorf("doing my thing: %w", err) }
그렇다면 이를 테스트에 어떻게 활용할까요? 이제 함수가 변수(customExit)로 바뀌었으므로 값을 우리가 원하는 다른 것으로 바꿀 수 있습니다. 그렇군요...
err := myFunc() if err != nil { fmt.Printf("doing my thing: %v", err) os.Exit(1) }
이것은 훨씬 더 단위 테스트 친화적인 접근 방식입니다. 사용된 종료 코드가 올바른지, 그리고 실제로 종료 함수를 호출했는지 확인할 수 있습니다.
표면적으로는 좋아 보이지만 한 가지 큰 문제가 있습니다. 테스트가 통과하면 프로그램이 계속 진행되고 종료할 것으로 예상했던 나머지 함수가 실행됩니다. 테스트 설정으로 인해 나머지 실행이 유효하지 않고 패닉을 일으키는 등 테스트에 문제가 발생하더라도 계속됩니다.
글쎄, 이건 좀 극단적인 것 같네요!
설명해야 할 것 같습니다... 일반적으로 "잘 관리되는" 회사에서는 모든 코드 줄이 고객 앞에 표시되기 전에 작동하는지 확인해야 합니다. 위의 기술을 사용하면 귀하가 양호하다는 것을 증명하는 올바른 적용 범위 지표를 생성하지 못할 수도 있습니다. 비록 추론하기에는 사소한 일이라 할지라도.
위의 모든 예에서는 오류가 발생하면 이를 확인하여 무엇을 해야 할지 결정해야 한다고 가정했습니다(복수하고 종료). 오류가 있었는지 확인하지 않고 종료할 수 있다면 얼마나 좋을까요?
우리가 무엇을 할 수 있는지 살펴보겠습니다.
err := myFunc() if err != nil { return fmt.Errorf("doing my thing: %w", err) }
위의 예를 살펴보세요. 기능은 동일하지만 이제 myFunc 구현이 훨씬 간단해졌습니다. 조건이 없습니다. 자체 테스트에서 checkExit 함수의 구현을 확인할 수 있습니다. 즉, myFunc()의 새로운 기능을 훨씬 더 쉽게 확인할 수 있습니다.
오류가 있는 경우 코드를 복잡하게 만들지 않고도 오류가 처리될 것이라는 확신을 가질 수 있는 새로운 라이브러리인 gobail이 만들어졌습니다. 다음과 같습니다:
err := myFunc() if err != nil { fmt.Printf("doing my thing: %v", err) os.Exit(1) }
이 라이브러리는 이를 입증하기 위해 적용 범위 측정 기준을 통해 완전히 테스트되었습니다. 오류를 건너뛸 염려 없이 안전하게 사용할 수 있습니다. 또한 다음과 같이 2개의 반환 값이 있는 함수를 처리합니다.
type ExitFunc func(code int) var customExit ExitFunc = os.Exit func myFunc() { err := someOtherFunc() if err != nil { fmt.Printf("doing my thing: %v", err) customExit(1) } }
모든 문제를 일으키는 오류도 포함되어 있다는 점에 유의하세요.
종료하는 대신 패닉이 호출될 때 프로그램에서 스택 추적 및 기타 상황별 정보를 인쇄하여 패닉을 발생시킬 수도 있습니다. 자세한 내용은 문서를 살펴보세요.
gobail로 소프트웨어를 작성하다 보면 외부 라이브러리와 대화할 때 대부분 gobail을 사용해야 한다는 것을 알게 될 것입니다. 여기에는 모든 오류 사례를 처리하기 위해 일반적으로 작성해야 하는 추가 코드가 있으며 Return 또는 Return2에 대한 호출로 래핑할 수 있으며 필요할 때 종료한다고 가정할 수 있습니다.
오류를 자세히 처리하는 대신 프로그램을 종료하는 것이 바람직한 경우도 있습니다. 고베일 라이브러리는 이를 증명하기 위한 세세한 부분에 대해 걱정하지 않으셔도 되도록 제작 및 검증되었습니다.
개선할 수 있는 부분을 발견했거나 제안 사항이 있는 경우 저장소에 PR이나 문제를 제기하면 개발자가 가능한 한 이에 착수할 것입니다!
위 내용은 승리를 위해 일찍 그만 두세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!