2010-01-22 1 views
19

이것은 특정 언어보다 일반적인 프로그래밍 관련 질문입니다. 나는 여러 가지 appraoches를 보았고, 붙잡는다.함수 내부 및 외부에서 캐치 블록을 시도하고 오류 처리

하나는 필요한 데이터에 대해 사전 처리를 수행하고 적절한 인수를 사용하여 함수를 호출 한 다음 try/catch 블록으로 래핑하십시오.

다른 하나는 단순히 함수를 호출하여 데이터를 전달하고 함수 내에서 try 캐치에 의존하며 오류가 발생하면 true/false 플래그를 반환합니다.

세 번째는 함수 외부와 내부의 try catch와의 조합입니다. 그러나 함수가 catch catch를 시도하면 뭔가 잡기 위해 try catch 블록에 대한 또 다른 예외를 throw합니다.

오류 제어를위한 이러한 방법의 장점/단점에 대한 의견이나 수락 된 표준이있는 경우? 내 인터넷 검색 기술은 이것에 대한 정확한 데이터를 찾지 못했습니다.

답변

15

일반적으로 예외를 실제로 처리 할 수있는 경우에만 예외를 포착해야합니다.

로그를 남기는 것 외에 다른 목적으로 예외를 잡는 것은 의미가 없습니다. 예외는 예외가 기록 될 수 있도록 "최상위 레벨"에서 캐치되어야한다는 것입니다. 다른 모든 코드는 예외를 로그 할 코드로 전파 할 수 있어야합니다.

+1

+1 : 그리고 함수가 무언가를 끝내기위한 대체 전략을 포함하고있을 때에 만 예외를 처리 할 수 ​​있습니다. –

+1

나는 초기 throw보다 더 많은 문맥으로 유용한 로깅을 생성하기 위해 예외를 잡는 것이 때때로 유용 할 수 있다고 생각한다. 그 후에 예외를 처리 할 수 ​​없다면 다시 던지십시오. – extraneon

+1

"자세한 정보"가 핵심입니다. 추가 정보없이 로깅 만하면 더 높은 수준으로 대기해야합니다. –

2

응용 프로그램의 모든 "모듈"은 자체 입력 매개 변수를 처리합니다. 일반적으로 가능한 한 빨리 문제를 찾아야하며 응용 프로그램의 다른 부분에 쓰레기를 넘겨서는 안됩니다. 그러나 예외가 있습니다. 때로는 입력 매개 변수의 유효성을 검사 할 때 기본적으로 호출자에서 호출 수신자가 수행해야하는 작업 (예 : 정수 구문 분석)을 다시 구현해야합니다. 이 경우 일반적으로 작업을 시도하고 작동하는지 여부를 확인하는 것이 좋습니다. 또한, 당신이 그들을하지 않고 성공을 예측할 수없는 몇 가지 작업이 있습니다. 예를 들어 파일에 쓰기 전에 파일에 쓸 수 있는지 여부를 신뢰할 수 없는지 확인할 수 없습니다. 확인 후에 다른 프로세스가 즉시 파일을 잠글 수 있습니다.

+0

이 질문에 대답하지 않는 것 같습니다. 그것은 예외가 일어날 수있는 방법을 검토하는 것처럼 보입니다. –

+0

@S.Lott : OP가 오류를 처리하고 부울 성공/실패 값을 반환하기 위해 다른 모듈에 의존해야하는지 또는 예외를 발생시키고 호출 스택에서 더 높게 잡는 지 여부를 OP가 알고 싶어하는 것처럼 이해했습니다. 아마도 오해했을 것입니다. . 그것은 꽤 길다. 그리고 나는 그것이 적어도 그것의 일부를 다룬다고 생각한다. –

0

나는 일반적으로 메서드의 호출자로서 어떤 식 으로든 예외를 사용할 수 있는지 (다른 접근 방식을 취함으로써 예외를 복구 할 수 있는지) 또는 예외가 발생해도 아무런 차이가없고 단지 잘못되었을 경우 고려합니다. 그래서 전의 경우 예외를 던지는 메소드를 선언 할 것이고 후자에서는 메소드의 내부에서 그것을 잡아서 호출자를 귀찮게하지 않을 것입니다.

0

잡기 예외에 대한 유일한 질문은 "뭔가 완료하기위한 여러 가지 전략이 있습니까?"입니다.

일부 기능은 일부 예외를 의미있게 잡아 내고 알려진 예외가 발생한 경우 대체 전략을 시도 할 수 있습니다.

다른 모든 예외가 발생합니다.

대체 전략이없는 경우 예외가 발생합니다.

예외를 포착 (및 소거)하는 기능이 거의 필요하지 않습니다. 예외는 무엇인가 잘못되었다는 것을 의미합니다. 응용 프로그램은 전체적으로 처리되지 않은 예외를 인식해야합니다. 최소한 로그에 기록해야하며 더 많은 작업을 수행해야합니다. 종료하거나 재시작하십시오.

4

나는 이것을 생각하는 가장 좋은 방법은 프로그램 상태에 있다고 생각합니다. 실패한 작업으로 인해 프로그램 상태가 손상되는 것을 원하지는 않습니다. This paper은 "예외 안전"개념을 설명합니다.

일반적으로 함수가 보장해야하는 예외 안전 수준을 결정해야합니다. 레벨은

기본 보증은 단순히 예외 또는 기타 오류의 얼굴에 어떤 자원이 강한 유출 없음을 의미

  • 강한 보증이
  • 이 보장 NoThrow

    • 기본 Guarnantee 있습니다 보증에서는 프로그램 상태가 예외 이전으로 롤백되고 nothrow 메소드가 결코 예외를 throw하지 않는다고 말합니다.

      예기치 않은 런타임 오류가 발생하면 개인적으로 예외를 사용합니다. 예상치 못한 결과는 정상적인 작동 과정에서 이러한 오류가 발생해서는 안된다는 것을 의미합니다. 런타임이란 오류가 내 컨트롤의 외부에있는 일부 외부 구성 요소의 상태 때문인 것을 의미합니다. 이는 내 부분의 논리 오류 때문이 아닙니다. 논리 오류를 catch하는 ASSERT() 사용하고 예상 된 오류 부울 반환 값을 사용합니다.

      왜? ASSERT는 릴리스 코드로 컴파일되지 않으므로 사용자가 내 자신의 오류를 확인하는 데 부담을주지 않습니다. 그것이 단위 테스트와 ASSERTS의 목적입니다. 예외를 던지기 때문에 부울은 잘못된 메시지를 줄 수 있습니다. 예외는 또한 비쌀 수있다. 응용 프로그램 실행의 정상적인 과정에서 예외가 발생하면 MS Visual Studio 디버거의 우수한 "catch on throw"예외 기능을 사용할 수 없습니다. 여기서 디버거가 프로그램을 중단 할 수 있습니다. 예외입니다. 처리되지 않은 (충돌하는) 예외에서만 멈추는 디폴트보다는 오히려 던져진다.

      기본 보증에 대한 C++ 기술을 보려면 google "RAII"(Resource Acquisition is Initialiation)를 참조하십시오. 이것은 생성자가 리소스를 할당하고 소멸자가 리소스를 해제하는 객체에 리소스를 래핑하는 기술입니다. C++ 예외가 스택을 풀면 예외가 발생해도 리소스가 해제됩니다. 이 기술을 사용하여 예외 상황에서 프로그램 상태를 롤백 할 수 있습니다. "Commit"메서드를 개체에 추가하기 만하면 개체가 소멸되기 전에 커밋되지 않은 경우 소멸자에서 프로그램 상태를 복원하는 "롤백"작업을 실행하십시오.

  • +0

    노 무보증이란 무엇입니까? 이것은 C++일까요? Java 및 Python에는 catch 할 수없는 많은 오류가 있습니다. –

    +0

    NoThrow는 나머지 보증을 가능하게하는 데 필요한 보증입니다. C의 'Free()'와 같은 소멸자와 초기화 도구는 NoThrow 여야합니다. 즉, 결코 예외를 throw하지 않습니다. RollBack() 함수도 절대로 throw해서는 안됩니다. 새로운 예외를 생성하지 않고 프로그램 상태를 정리할 수 없다면 프로그램 상태가 손상되지 않는다고 보장 할 수 없다는 것을 의미합니다. NoThrow 조작을 작성하는 세 가지 f}이 있습니다. 단지 휴지 작업 만 작성하십시오. 던져 넣을 수 없다는 것을 논리적으로 보장하거나 예외를 삼키는 try-catch를 넣으십시오. –

    +0

    즉, 모든 시간을 막을 수는 없다는 것을 알고있는 3 가지 예외가 있습니다. ThreadAbort 예외 (.NET 언어로 불리는 것, 다른 언어에서는 다른 동등한 요소가있을 수 있음), 메모리 부족 예외 및 스택 오버플로 예외입니다. 3 번 모두는 제한없는 시간, 메모리 및 호출 재귀를 사용할 수있는 추상 개념의 프로그램을 위반 한 것입니다. 그들 중 누구에게도 할 수있는 일은별로 없습니다. 다행히 대부분 대다수의 사람들이 맞지 않는 프로그램을 설계 할 수 있습니다. –

    1

    내가 만난 예외 처리에 대한 실제 규칙은 없지만 적용하려는 일반적인 규칙이 많습니다.

    시스템의 하위 레이어에서 예외가 처리되는 경우에도 시스템의 진입 점에 catch 예외 처리기가 모두 있는지 확인하십시오 (예 : 새 스레드 (예 : Runnable), Servlet, MessasgeDrivenBean을 구현할 때) 서버 소켓 등). 시스템이 어떻게 계속되어야하는지 (로그 및 재시도, 오류와 함께 종료, 트랜잭션 롤백) 최종 결정을 내려야하는 경우가 종종 있습니다.

    finally 블록 내에서 절대 실행을 포기하지 않으면 원래의 예외를 잃게됩니다. 중요하지 않은 오류로 실제 문제를 숨 깁니다.

    이외에도 구현하는 기능에 따라 다릅니다. 나머지 항목을 다시 시도하거나 전체 목록을 중단해야합니까?

    로그 예외를 다시 발생 시키면 로그에 노이즈가 추가되므로 로깅을 피하십시오.