오류 처리를 구현하는 방법 [닫기]


13

몇 년 동안 전문가 수준으로 프로그래밍했지만 오류 처리를 완전히 이해하지 못합니다. 내 응용 프로그램은 제대로 작동하지만 오류 처리는 전문가 수준에서 구현되지 않으며 여러 기술이 혼합되어 있습니다.

내 오류 처리 뒤에 구조가 없습니다. 전문가 수준에서 구현되는 방법을 배우고 이해하고 싶습니다. 이것은 내가 지식이 부족한 영역입니다.

로직 플로우에서 확인할 예외를 언제 사용해야하고 성공 상태를 언제 리턴해야합니까? 예외를 혼합하고 상태를 반환해도 괜찮습니까?

주로 C #으로 코딩합니다.


2
왜 다운 투표? 오류 처리 구현 및 수행 방법에 대해 심각한 질문을하고 있습니다. 이것이 프로그래머들에게 그러한 질문을하기 가장 좋은 장소가 아니라면 어디에 있습니까? 사람들이 그러한 질문에 투표 할 때 다른 질문이 없기 때문에 실제로 버그가 있습니다. 웹에서 신뢰할 수있는 답변과 가능한 리소스를 얻을 수있는 유일한 곳일 것입니다. 따라서 다른 사람들이 Google에 대답하기가 쉽지 않을 것이라는 의문을 표명하는 대신?
제임스 제프리

6
귀하의 질문은 매우 광범위합니다. 코딩 목표를 달성하지 못한 방법에 대한 특정 예를 관련하여 범위를 좁힐 수 있습니다.
Andyz Smith

웹에는 오류 처리에 대한 많은 기사가 있습니다. 다음을 시도해보십시오. msdn.microsoft.com/en-us/library/seyhszts.aspx
Nir Kornfeld

답변:


25
  1. 예외적 인 일, 너무 자주 발생할 것으로 예상 할 수없는 일, 문제가 있음을 나타내는 일에는 예외를 사용하십시오. 예를 들어 네트워크가 다운 된 경우 웹 서버에서는 예외입니다. 데이터베이스를 사용할 수 없으면 문제가 있음을 의미합니다. 구성 파일이 없으면 사용자가 엉망이 된 것입니다.

  2. 잘못된 코드를 처리하기 위해 예외를 사용하지 마십시오. 코드의 정확성을 확인하려면 어설 션을 사용하거나 .NET Framework 4 이상에서 코드 계약 (어설 션을 대체하고 특히 유용한 추가 기능이있는 코드 계약)을 사용해야합니다.

  3. 예외가 아닌 경우에는 예외를 사용하지 마십시오. 사용자가 숫자를 입력하라는 요청을 받았을 때 "dog"을 입력했다는 사실은 예외가 아닙니다.

  4. 예외 유형을 선택할 때주의하십시오. 필요할 때 자신 만의 유형을 만드십시오. 부모를 잡는 것이 아이들을 잡을 것이라는 점을 명심하면서 상속을 신중하게 선택하십시오. 절대로 throw Exception.

  5. 오류에 리턴 코드를 사용하지 마십시오. 오류 코드는 쉽게 마스킹되고 무시되며 잊혀집니다. 오류가 있으면 처리하거나 상위 스택으로 전파하십시오.

  6. 메소드가 오류를 리턴 할 것으로 예상되고 오류가 예외가 아닌 경우, 열거 형을 사용하고 오류 번호는 절대 사용하지 마십시오. 예:

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }
    

    의 의미 LoadOperationResult.ServerUnavailable, LoadOperationResult.ParsingError데이터를 분석 할 수 없음 -, 등 그 코드를 서버가 다운이다 (12 개) 수단 및 코드 (13)를 기억, 말보다 훨씬 더 명시 적입니다.

  7. 특정 도메인에서 일하는 모든 개발자에게 알려진 공통 코드를 참조 할 때 오류 코드를 사용하십시오. 예를 들어 HTTP 404를 찾을 수 없음 또는 HTTP 500 내부 서버 오류에 대한 열거 형 값을 다시 만들지 마십시오.

  8. 부울에주의하십시오. 조만간 특정 방법의 성공 여부뿐만 아니라 그 이유를 알고 싶을 것입니다. 예외와 열거는 훨씬 강력합니다.

  9. 스택의 맨 위에 있지 않는 한 모든 예외를 포착하지 마십시오. 예외가 발생하면 처리 할 준비가되어 있어야합니다. 모든 것을 잡으면 코드가 올바르게 실행되는지 신경 쓰지 않는다는 것을 알 수 있습니다. 이렇게하면 "지금이 문제를 해결하는 방법을 검색하고 싶지 않습니다"를 해결할 수 있지만 조만간 당신을 해칠 것입니다.

  10. C #에서는 다음과 같은 예외를 다시 발생시키지 마십시오.

    catch (SomeException ex)
    {
        ...
        throw ex;
    }
    

    당신은 스택을 깨고 있기 때문에. 대신이 작업을 수행하십시오.

    catch (SomeException)
    {
        ...
        throw;
    }
    
  11. 예외 메시지를 작성할 때 노력하십시오. throw Exception("wrong data")또는 같은 것을 몇 번 이나 보았습니다 throw Exception("shouldn't call this method in this context"). 6 개월 후 자신을 포함한 다른 개발자들은 어떤 데이터가 잘못되었는지, 왜 어떤 이유를 문맥에서 어떤 방법으로 호출해야하는지, 어떤 문맥으로 정확하게 호출하지 않아야하는지 전혀 모를 것입니다.

  12. 사용자에게 예외 메시지를 표시하지 마십시오. 그것들은 평범한 사람들에게는 기대되지 않으며 종종 개발자 스스로 읽을 수 없습니다.

  13. 예외 메시지를 현지화하지 마십시오. 현지화 된 메시지에 대한 설명서를 검색하는 것은 매우 소중합니다. 모든 메시지는 영어와 영어로만 작성되어야합니다.

  14. 예외 및 오류에만 집중하지 마십시오. 로그도 매우 중요합니다.

  15. .NET에서 메소드의 XML 문서에 예외를 포함시키는 것을 잊지 마십시오.

    /// <exception cref="MyException">Description of the exception</exception>

    XML 문서에 예외를 포함 시키면 라이브러리를 사용하는 사람이 훨씬 쉽게 작업 할 수 있습니다. 어떤 예외가 메소드에 의해 발생 될 수 있는지 추측하는 것보다 더 성가신 것은 없습니다.

    이런 점에서 Java 예외 처리 는보다 강력하고 효과적인 접근 방법을 제공합니다. 호출 된 메소드에 의해 잠재적으로 발생하는 예외를 처리하거나 처리하지 않는 예외를 발생시킬 수 있음을 자신의 메소드로 선언하여 상황을 특히 투명하게 만듭니다.


¹ 이것은 언어가 예외를 확인하고 확인하지 않았기 때문에 예외와 오류 사이의 Java 구별이 꽤 쓸모없고 혼란 스럽다는 것을 알았습니다. 다행히 .NET Framework에는 예외 만 있고 오류는 없습니다.


나는 이것에서 약간의 인용문을 배웠습니다. 목록의 출처를 물어볼 수 있습니까? 현장 또는 개인 경험? 어느 쪽이든 예외적 인 직업 (그녀는 그것을 얻는가?).
Shelby115

@ Shelby115 : 목록은 스티브 맥코넬 (Steve Mcconnell)의 스택 익스체인지, 개인 경험 및 코드 완성 순서로 제공됩니다.
Arseni Mourzenko

훌륭한 답변 인 @MainMa에게 감사합니다! 나는 대학에있을 때 Code Complete를 소유하고 있었지만 누군가가 그것을 훔쳤습니다. 나는 그것을 읽지 못했습니다.
James Jeffery

@JamesJeffery : 그런 다음 도서관에서 두 번째 판을 빌리거나 하나를 구입하십시오. 그것은 돈이 가치가있는 드문 개발 관련 책 중 하나입니다.
Arseni Mourzenko

@MainMa 아마존에서 방금 주문 해 주셔서 감사합니다. DI는 Clean Code를 소유하고 있으며 7 장을 잊어 버렸습니다.
James Jeffery

1

MainMa의 목록은 매우 완벽하다고 생각합니다. 나는 내 자신의 몇 가지를 추가 할 것입니다 :

  1. 예외를 분류하는 방법에 대한 Eric Lippert의 기사 를 읽으십시오 . 코드에서 실제로 버그가있는 예외를 포착하지 않는 것에 대한 그의 요점이 특히 중요합니다. 대신 코드를 수정하십시오!
  2. 예외가 발생할 수 있고 이에 대해 무언가를 할 수 있다는 것을 알고 있다면 처리 할 수 ​​있지만 시도 범위를 제한하고 예상되는 특정 예외를 포착하십시오. 즉, 이렇게하지 마십시오 :

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

대신 이것을하십시오 :

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • 제어 흐름에 예외를 사용하지 마십시오. 예를 들어, 조회 대화 상자에서 ClientNotFoundException을 발생시키지 마십시오 (이 상황에서는 클라이언트를 찾을 수 없음) 예외가 발생하면 호출 코드에 "결과를 찾을 수 없음"메시지가 표시 될 것으로 예상합니다.

  • 예외를 삼키지 마십시오!

  • 실제로 예외를 처리하면 3 가지만 의미 할 수 있습니다.

    1. 조작을 재 시도하십시오. 일시적인 문제인 경우에만 유효합니다.
    2. 대안을 시도하십시오.
    3. 문제에 대해 다른 사람에게 알리십시오. 알림이 실행 가능한 경우에만 유효합니다. 즉, 사용자가 알림을 수행 할 수 있습니다.

    이러한 옵션 중 어느 것도 적용되지 않으면 해당 예외를 포착해서는 안됩니다. 그러나 로그를 기록한 다음 작업을 취소하거나 종료해야합니다. 물론 이것은 정확성 대 견고성에 대한 귀하의 요구 사항에 달려 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.