[language-agnostic] 예외 또는 오류 코드에 대한 규칙

어제 저는 선호하는 오류보고 방법에 대해 동료와 열띤 토론을 벌였습니다. 주로 우리는 응용 프로그램 계층 또는 모듈 간의 오류보고를위한 예외 또는 오류 코드의 사용에 대해 논의했습니다.

오류보고를 위해 예외를 발생 시키거나 오류 코드를 반환할지 여부를 결정하기 위해 어떤 규칙을 사용합니까?



답변

높은 수준의 항목에서는 예외입니다. 낮은 수준의 오류 코드에서.

예외의 기본 동작은 스택을 풀고 프로그램을 중지하는 것입니다. 스크립트를 작성하고 사전에없는 키를 찾으면 오류 일 수 있으며 프로그램을 중지하고 그것에 대해 모두 알고 있습니다.

그러나 가능한 모든 상황에서 동작을 알아야 하는 코드를 작성하고 있다면 오류 코드를 원합니다. 그렇지 않으면 내 함수의 모든 줄에서 발생할 수있는 모든 예외를 알아야합니다 (이게 얼마나 까다로운 지 알아 보려면 항공사접지 한 예외를 읽어보십시오 ). 모든 상황 (불행한 상황 포함)에 적절하게 반응하는 코드를 작성하는 것은 지루하고 어렵지만, 오류 코드를 전달하기 때문이 아니라 오류없는 코드를 작성하는 것이 지루하고 어렵 기 때문입니다.

모두 레이몬드 첸 조엘은 모든 것에 예외를 사용에 대한 몇 가지 설득력있는 주장을 만들었습니다.


답변

나는 일반적으로 예외를 선호한다. 왜냐하면 그것들은 더 많은 문맥 정보를 가지고 있고 프로그래머에게 더 명확한 방식으로 오류를 전달할 수 있기 때문이다.

반면에 오류 코드는 예외보다 가볍지 만 유지하기가 더 어렵습니다. 오류 검사는 실수로 생략 될 수 있습니다. 오류 코드는 모든 오류 코드가 포함 된 카탈로그를 유지 한 다음 결과를 켜서 어떤 오류가 발생했는지 확인해야하므로 유지 관리하기가 더 어렵습니다. 여기에서 오류 범위가 도움이 될 수 있습니다. 왜냐하면 우리가 관심있는 유일한 것이 오류가 있는지 여부뿐이라면 확인하는 것이 더 간단하기 때문입니다 (예 : 0보다 크거나 같은 HRESULT 오류 코드는 성공이고 0보다 작 으면 실패). 개발자가 오류 코드를 확인하는 프로그래밍 강제가 없기 때문에 실수로 생략 될 수 있습니다. 반면에 예외는 무시할 수 없습니다.

요약하면 거의 모든 상황에서 오류 코드보다 예외를 선호합니다.


답변

나는 예외를 선호한다.

  • 논리의 흐름을 방해한다
  • 더 많은 기능 / 기능을 제공하는 클래스 계층 구조의 이점
  • 적절하게 사용되면 광범위한 오류를 나타낼 수 있습니다 (예 : InvalidMethodCallException도 LogicException입니다. 둘 다 런타임 전에 감지 할 수 있어야하는 코드에 버그가있을 때 발생하기 때문입니다).
  • 오류를 개선하는 데 사용할 수 있습니다 (예 : FileReadException 클래스 정의는 파일이 있는지 또는 잠겨 있는지 여부를 확인하는 코드를 포함 할 수 있습니다).

답변

함수 호출자는 오류 코드를 무시할 수 있습니다. 예외는 최소한 어떤 방식 으로든 오류를 처리하도록 강제합니다. 그들의 버전이 빈 캐치 핸들러를 갖는 것이더라도 (한숨).


답변

오류 코드에 대한 예외는 의심 할 여지가 없습니다. 오류 코드와 마찬가지로 예외에서 많은 이점을 얻을 수 있지만 오류 코드의 단점없이 훨씬 더 많은 이점을 얻을 수 있습니다. 예외에 대한 유일한 노크는 오버 헤드가 약간 더 많다는 것입니다. 그러나 오늘날에는 거의 모든 응용 프로그램에서 이러한 오버 헤드를 무시할 수있는 수준으로 간주해야합니다.

다음은 두 가지 기술을 논의, 비교 및 ​​대조하는 몇 가지 기사입니다.

더 많은 정보를 얻을 수있는 좋은 링크가 있습니다.


답변

나는 두 모델을 절대 혼합하지 않을 것입니다. 오류 코드를 사용하는 스택의 한 부분에서 예외를 사용하는 상위 부분으로 이동할 때 하나에서 다른 모델로 변환하기가 너무 어렵습니다.

예외는 “메서드 또는 서브 루틴이 요청한 작업을 수행하는 것을 중지하거나 방해하는 모든 것”에 대한 것입니다 … 불규칙성 또는 비정상적인 상황 또는 시스템 상태 등에 대한 메시지를 다시 전달하지 마십시오. 반환 값 또는 참조를 사용하십시오. (또는 출력) 매개 변수.

예외는 메서드의 기능에 의존하는 의미론으로 메서드를 작성 (활용) 할 수있게합니다. 즉, Employee 객체 또는 직원 목록을 반환하는 메서드를 입력하여이를 수행 할 수 있으며 호출하여 사용할 수 있습니다.

Employee EmpOfMonth = GetEmployeeOfTheMonth();

오류 코드를 사용하면 모든 메서드가 오류 코드를 반환하므로 호출 코드에서 사용할 다른 것을 반환해야하는 메서드의 경우 해당 데이터로 채워질 참조 변수를 전달하고 해당 데이터에 대한 반환 값을 테스트해야합니다. 모든 함수 또는 메서드 호출에서 오류 코드를 처리하고 처리합니다.

Employee EmpOfMonth;
if (getEmployeeOfTheMonth(ref EmpOfMonth) == ERROR)
    // code to Handle the error here

각 메서드가 한 가지 간단한 작업 만 수행하도록 코딩하는 경우 메서드가 원하는 목적을 달성 할 수 없을 때마다 예외를 throw해야합니다. 예외는 이러한 방식으로 오류 코드보다 훨씬 풍부하고 사용하기 쉽습니다. 코드가 훨씬 깔끔합니다. “일반적인”코드 경로의 표준 흐름은 메서드가 원하는 작업을 수행 할 수있는 경우에만 엄격하게 적용 할 수 있습니다. 그런 다음 코드를 정리하거나 처리 할 수 ​​있습니다. 메서드가 성공적으로 완료되지 못하게하는 나쁜 일이 발생하는 “예외적 인”상황은 일반 코드에서 격리 될 수 있습니다. 또한 예외가 발생한 곳에서 예외를 처리 할 수없고 스택을 UI로 전달해야하는 경우 (더 나쁜 경우에는 중간 계층 구성 요소에서 UI로 연결) 예외 모델을 사용하여


답변

과거에는 오류 코드 캠프에 참여했습니다 (C 프로그래밍을 너무 많이 했음). 그러나 이제 나는 빛을 보았다.

예, 예외는 시스템에 약간의 부담이됩니다. 그러나 코드를 단순화하여 오류 (및 WTF) 수를 줄입니다.

따라서 예외를 사용하되 현명하게 사용하십시오. 그리고 그들은 당신의 친구가 될 것입니다.

참고로. 어떤 방법으로 어떤 예외를 던질 수 있는지 문서화하는 법을 배웠습니다. 불행히도 이것은 대부분의 언어에서 필요하지 않습니다. 그러나 적절한 수준에서 적절한 예외를 처리 할 가능성이 높아집니다.