문제

우리는 회사 시스템의 예외 처리 중 하나를 검토 중이며 몇 가지 흥미로운 점을 발견했습니다.

대부분의 코드 블록(모두는 아니지만)은 try/catch 블록 내부에 있고, catch 블록 내부에는 새로운 BaseApplicationException이 발생합니다. 이는 엔터프라이즈 라이브러리에서 발생하는 것으로 보입니다.이 작업을 수행하면 이점을 볼 수 없기 때문에 여기서 약간의 문제가 발생합니다.(한 번에 다른 예외를 던지는 또 다른 예외를 던지기) 시스템을 사용하고있는 개발자 중 한 명은이 수업이 예외를 게시하는 (이메일 및 그와 같은 물건을 보내기) 책임자라고 말했지만 너무 확신하지 못했기 때문이라고 말했습니다.코드를 살펴보는 데 시간을 투자한 후에는 환경에 대한 정보를 수집하고 게시하는 것뿐이라고 자신있게 말할 수 있습니다.

내 질문은 다음과 같습니다- try { } catch { } 블록 내부에 모든 코드를 래핑하고 새로운 예외를 발생시키는 것이 합리적입니까?그렇다면 왜 그렇습니까?이점은 무엇입니까?

내 개인적인 의견은 HttpModule을 사용하고, Application 이벤트의 Error 이벤트에 등록하고, 모듈 내부에서 필요한 작업을 수행하는 것이 훨씬 쉬울 것이라는 것입니다.이 길을 따라가면 뭔가를 놓치게 될까요?단점이 있나요?

귀하의 의견을 높이 평가합니다.

도움이 되었습니까?

해결책

절대1 catch (Exception ex).기간2.발견할 수 있는 다양한 종류의 오류를 모두 처리할 수 있는 방법은 없습니다.

절대3 처리할 수 없거나 추가 정보를 제공할 수 없는 경우 예외 파생 유형을 포착합니다(후속 예외 처리기에서 사용됨).오류 메시지를 표시하는 것은 ~ 아니다 같은 손질 오류.

내 머리 꼭대기에서 이에 대한 몇 가지 이유가 있습니다.

  • 잡아서 다시 던지는 데 비용이 많이 듭니다
  • 결국 스택 추적이 손실됩니다.
  • 코드의 신호 대 잡음 비율이 낮습니다.

처리하는 방법을 알고 있다면 특정한 예외(그리고 애플리케이션을 오류 이전 상태로 재설정)를 포착합니다.(그래서 이렇게 불린다. 예외 손질.)

포착되지 않은 예외를 처리하려면 적절한 이벤트를 수신하세요.WinForms를 수행할 때 다음 사항을 들어야 합니다. System.AppDomain.CurrentDomain.UnhandledException, 그리고 - 당신이 하고 있는 일이라면 Threading - System.Windows.Forms.Application.ThreadException. 웹 앱의 경우 유사한 메커니즘이 있습니다(System.Web.HttpApplication.Error).

애플리케이션의 (비)특정 예외에서 프레임워크 예외를 래핑하는 경우(예: throw new MyBaseException(ex);):정말 무의미하고, 나쁜 냄새가 납니다.4


편집하다

1 절대 @Chris가 의견에서 지적한 것처럼 특히 엔지니어링과 관련하여 매우 가혹한 단어입니다.나는 이 답변을 처음 썼을 때 원칙을 중요하게 생각했음을 인정하겠습니다.

2,3 보다 1.

4 당신이 테이블에 새로운 것을 가져오지 않더라도 나는 여전히 이것을 지지합니다.잡았다면 Exception ex 여러 가지 방법으로 실패할 수 있는 메서드의 일부로서 현재 메서드는 이를 서명에 반영해야 한다고 생각합니다.아시다시피 예외는 메서드 서명의 일부가 아닙니다.

다른 팁

질문을 올바르게 읽고 있다면, 예외를 가로 채지 않는 시도 / 캐치를 구현하는 것을 구현하는 것은 모든 예외를 포착하는 것입니까, 아니면 특정한 예외입니까?) 다른 예외를 던지는 것은 일반적으로 나쁜 것입니다. .

단점 :

최소한 스택 추적 정보를 잃을 것입니다 - 당신이 볼 수있는 스택은 새로운 예외가 발생하는 방법으로 만 확장됩니다. 잠재적으로 좋은 디버그 정보를 잃어 버릴 수 있습니다.

예외를 포착하는 경우, 덜 중요한 예외로 OutefMemory 또는 StackoverFlow와 같은 중요한 예외를 마스킹 할 위험이 있으며, 따라서 프로세스가 찢어 졌을 때 프로세스를 실행해야합니다.

가능한 이점 :

일부 매우 구체적인 경우에는 디버그 값이 많지 않은 예외 (데이터베이스에서 돌아 오는 일부 예외)가없는 예외를 취하고 컨텍스트를 추가하는 예외와 예를 들어 랩핑 할 수 있습니다.

그러나 거의 모든 경우에 이것은 나쁜 냄새이며주의해서 사용해야합니다.

일반적으로 해당 위치에서 할 수있는 현실적인 일이있을 때만 예외를 포착해야합니다. 즉, 회복, 롤백, B 계획 B 등. . 해당 위치에 구체적이고 유용한 데이터가있는 경우 원래의 예외를 확대하여 디버깅을 지원할 수있는 경우에만 새로운 예외를 포착하고 던져야합니다.

나는 시도/ 캐치 블록을 사용해야하고 예외를 다시 제외하지 않는 생각의 학교 출신입니다. 오류가 발생할 가능성이있는 코드를 실행하는 경우 처리, 기록 및 반환해야합니다. 예외를 재확인하면 응용 프로그램 수명주기 후반에 다시 로그하는 목적으로 만 사용됩니다.

다음은 httpmodule을 사용하여 예외를 처리하는 방법에 대한 흥미로운 게시물입니다. http://blogs.msdn.com/rahulso/archive/2008/07/13/how-to-use-httpmodules-troubleshoot-your-asp-net-application.aspx 그리고 http://blogs.msdn.com/rahulso/archive/2008/07/18/asp-net-how-to-write-error-messages-into-a-text-file-using-a-simple-httpmodule. ASPX

확인해 보세요 엘마.그것은 당신이 말하는 것을 수행합니다.아주 잘.

나는 라이브러리를 생성할 때 항상 호출자가 처리해야 하는 예외 수를 줄이려고 노력합니다.예를 들어 SQL 데이터베이스에 연결하는 저장소 구성 요소를 생각해 보세요.SQL 클라이언트 예외부터 잘못된 캐스트 예외까지 이론적으로 발생할 수 있는 수많은 예외가 있습니다.이들 중 다수는 명확하게 문서화되어 있으며 컴파일 타임에 설명될 수 있습니다.따라서 가능한 한 많은 예외를 포착하여 단일 예외 유형(예: RepositoryException)에 배치하고 해당 예외가 호출 스택을 롤업하도록 합니다.

원래 예외가 유지되므로 원래 예외를 진단할 수 있습니다.그러나 호출자는 코드를 수많은 다른 catch 블록으로 뒤덮는 대신 단일 예외 유형 처리에 대해서만 걱정하면 됩니다.

물론 여기에는 몇 가지 문제가 있습니다.특히 호출자가 이러한 예외 중 일부를 처리할 수 있는 경우 RepositoryException을 둘러본 다음 내부 예외 유형을 켜서 처리해야 합니다.단일 예외 유형에 대해 단일 catch 블록을 갖는 것보다 덜 깨끗합니다.그러나 나는 그것이 큰 문제라고 생각하지 않습니다.

던져진 예외는 예외로 구현되어서는 안됩니다.

어쨌든, 나는이 기초의 기초 예점이 일반적인 다목적 예외이기 때문에, 더 많은 상황에 맞는 예외를 던지는 것이 좋을 것이라고 말할 것입니다. 따라서 데이터베이스에서 엔티티를 검색하려고 할 때 EntityNotFoundException을 원할 수 있습니다. 이런 식으로 디버깅 할 때 실제 문제를 찾기 위해 내부 예외와 스택 추적을 검색 할 필요가 없습니다. 이 기본 출판 예고가 예외에 대한 정보를 수집하는 경우 (내부 예외를 추적하는 것과 같은) 문제가되지 않아야합니다.

코드에서 예외가 실제로 발생하는 위치에 가까워 질 수없는 경우에만 httpmodule을 사용합니다. BaseApplicationException의 오류 정보에 따라 거대한 스위치 문인 HTTModule OnError 이벤트를 실제로 원하지 않습니다.

결론적으로, 박쥐에서 바로 문제의 근본을 알려주는 더 구체적인 예외를 제시 할 수있을 때 다른 예외를 던지는 것이 좋습니다.

내 경험에서 예외를 잡고 서버 (?) 객체에 오류를 추가하십시오. 이를 통해 .NET은 필요한 작업을 수행 한 다음 예외를 표시 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top