Java 또는 C #의 예외 관리를위한 모범 사례


117

내 응용 프로그램에서 예외를 처리하는 방법을 결정하는 중입니다.

예외에 대한 내 문제가 1) 원격 서비스를 통해 데이터에 액세스하거나 2) JSON 객체를 역 직렬화하는 데서 오는 경우가 많습니다. 안타깝게도 이러한 작업 (네트워크 연결 차단, 제어 할 수없는 잘못된 JSON 개체)에 대한 성공을 보장 할 수 없습니다.

결과적으로 예외가 발생하면 함수 내에서 예외를 포착하고 FALSE를 호출자에게 반환합니다. 내 논리는 호출자가 정말로 걱정하는 것은 작업이 성공했는지 여부가 아니라 왜 성공하지 못한 것인지라는 것입니다.

다음은 일반적인 방법의 일부 샘플 코드 (JAVA)입니다.)

public boolean doSomething(Object p_somthingToDoOn)
{
    boolean result = false;

    try{
        // if dirty object then clean
        doactualStuffOnObject(p_jsonObject);

        //assume success (no exception thrown)
        result = true;
    }
    catch(Exception Ex)
    {
        //don't care about exceptions
        Ex.printStackTrace();
    }
    return result;
}

이 접근 방식은 괜찮다고 생각하지만 예외를 관리하기위한 모범 사례가 무엇인지 알고 싶습니다 (실제로 호출 스택까지 예외를 버블 링해야합니까?).

주요 질문 요약 :

  1. 예외를 포착하고 버블 링하거나 공식적으로 시스템에 알리지 않는 것이 괜찮습니까 (로그 또는 사용자에게 알림을 통해)?
  2. 모든 것이 try / catch 블록을 필요로하지 않는 예외에 대한 모범 사례는 무엇입니까?

후속 조치 / 편집

모든 피드백에 감사 드리며 온라인에서 예외 관리에 대한 훌륭한 소스를 찾았습니다.

예외 관리는 상황에 따라 달라지는 것 중 하나 인 것 같습니다. 그러나 가장 중요한 것은 시스템 내에서 예외를 관리하는 방법에있어 일관성이 있어야한다는 것입니다.

또한 과도한 try / catch를 통해 코드 부패를 조심하거나 예외를 존중하지 않습니다 (예외는 시스템에 경고하는 것입니다. 다른 경고가 필요한 것은 무엇입니까?).

또한 이것은 m3rLinEz 의 예쁜 선택 주석입니다 .

나는 Anders Hejlsberg와 당신에게 동의하는 경향이 있습니다.

이 주석에서 예외를 처리 할 때 고려해야 할 몇 가지 질문이 있습니다.

  • 이 예외가 던져지는 점은 무엇입니까?
  • 그것을 처리하는 것이 어떻게 합리적입니까?
  • 호출자가 예외에 대해 정말로 신경을 쓰나요? 아니면 호출이 성공했는지 만 신경 쓰나요?
  • 호출자가 잠재적 인 예외를 관리하도록 강요하는 것이 적절합니까?
  • 언어의 우상을 존중하고 있습니까?
    • 부울과 같은 성공 플래그를 반환해야합니까? 부울 (또는 int)을 반환하는 것은 Java (Java에서는 예외를 처리 할 것임)보다 C 사고 방식에 가깝습니다.
    • 언어와 관련된 오류 관리 구조를 따르십시오 :)!

오라클 커뮤니티의 기사는 자바로되어 있지만 매우 광범위한 언어 클래스에 대한 일반적인 조언입니다. 좋은 기사, 내가 찾던 것.
토끼 토끼

답변:


61

예외를 잡아서 오류 코드로 바꾸려는 것이 이상하게 보입니다. Java와 C # 모두에서 후자가 기본값 인 경우 호출자가 예외보다 오류 코드를 선호한다고 생각하는 이유는 무엇입니까?

귀하의 질문 :

  1. 실제로 처리 할 수있는 예외 만 포착해야합니다. 대부분의 경우 예외를 포착하는 것은 옳은 일이 아닙니다. 몇 가지 예외 (예 : 스레드 간 예외 로깅 및 마샬링)가 있지만 이러한 경우에도 일반적으로 예외를 다시 던져야합니다.
  2. 코드에 try / catch 문이 많지 않아야합니다. 다시 말하지만, 아이디어는 처리 할 수있는 예외 만 포착하는 것입니다. 처리되지 않은 예외를 최종 사용자에게 다소 유용한 것으로 전환하기 위해 최상위 예외 처리기를 포함 할 수 있지만 그렇지 않으면 가능한 모든 위치에서 모든 예외를 포착하려고 시도해서는 안됩니다.

누군가가 예외 대신 오류 코드를 원하는 이유에 관해서는 ... 내 애플리케이션이 예외를 생성하더라도 HTTP가 여전히 오류 코드를 사용하는 것이 이상하다고 생각했습니다. HTTP가 예외를있는 그대로 전달할 수없는 이유는 무엇입니까?
Trejkaz

당신이 할 수있는 최선은 모나드에서 오류 코드를 래핑하는 것입니다
lindenrovio

@Trejkaz 보안 위험이 있기 때문에 예외 세부 정보를 사용자에게 반환하고 싶지 않습니다. 이것이 HTML 서버가 오류 코드를 반환하는 이유입니다. 오류 메시지를 반환하는 것도 현지화 문제이며 HTML의 크기가 커지고 반환 속도가 느려질 수 있습니다. 이 모든 것이 HTML 서버가 오류 코드를 반환한다고 생각하는 이유입니다.
Didier A.

"실제로 처리 할 수있는 예외 만 억제해야합니다."라고 말하는 것이 더 낫다고 생각합니다.
Didier A.

@didibus 보안 문제가 개발 과정에서 불편 함을 야기해야한다고 생각하는 이유는 무엇입니까? 나는 생산에 대해 아무 말도하지 않았다. 오류 메시지 현지화에 관해서는 전체 웹 사이트에 이미 해당 문제가 있으며 사람들은 대처하는 것으로 보입니다.
Trejkaz 2014

25

이것은 응용 프로그램과 상황에 따라 다릅니다. 라이브러리 구성 요소를 빌드하는 경우 예외를 표시해야하지만 구성 요소와 컨텍스트에 맞게 래핑해야합니다. 예를 들어 Xml 데이터베이스를 구축하고 파일 시스템을 사용하여 데이터를 저장하고 파일 시스템 권한을 사용하여 데이터를 보호한다고 가정 해 보겠습니다. 구현이 누출되므로 FileIOAccessDenied 예외를 발생시키고 싶지 않을 것입니다. 대신 예외를 래핑하고 AccessDenied 오류를 발생시킵니다. 구성 요소를 타사에 배포하는 경우 특히 그렇습니다.

예외를 삼켜도 괜찮은지. 시스템에 따라 다릅니다. 응용 프로그램이 실패 사례를 처리 할 수 ​​있고 실패 이유를 사용자에게 알리는 데 아무런 이점이없는 경우 실패를 기록하는 것이 좋습니다. 나는 항상 문제 해결을 돕고 그들이 예외를 삼키고 있다는 것을 발견하는 것이 좌절감을 느꼈습니다 (또는 내부 예외를 설정하지 않고 대신 새 것을 던지고 교체).

일반적으로 다음 규칙을 사용합니다.

  1. 내 구성 요소 및 라이브러리에서 처리하거나 이에 기반한 작업을 수행하려는 경우에만 예외가 발생합니다. 또는 예외에서 추가 컨텍스트 정보를 제공하려는 경우.
  2. 응용 프로그램 진입 점 또는 가능한 가장 높은 수준에서 일반적인 try catch를 사용합니다. 여기에 예외가 발생하면 기록하고 실패하게합니다. 이상적으로 예외는 여기에 오지 않아야합니다.

냄새가 나는 다음 코드를 찾습니다.

try
{
    //do something
}
catch(Exception)
{
   throw;
}

이와 같은 코드는 의미가 없으며 포함되어서는 안됩니다.


@Josh, 예외를 삼키는 것에 대한 좋은 지적이지만 단순히 예외를 삼키는 것이 허용되는 경우는 거의 없다고 생각합니다. 마지막 프로젝트에서 코드 조각은 필수 였고 냄새가났습니다. 그것들을 모두 기록하면 최악의 상황이되었습니다. 제 충고는 예외를 처리 할 수 ​​없다면 삼키지 마십시오.
smaclell

내가 말했듯이 모든 것은 앱과 특정 상황에 따라 다릅니다. 드물기는하지만 예외를 삼키는 경우가 있고 마지막으로했던 시간을 기억할 수 없습니다 .-) 아마도 내 로거를 작성하고 로그에 쓰기를했고 2 차 로그가 실패했을 때였습니다.
JoshBerke

코드는 포인트 역할을합니다. "throw"에서 중단 점을 설정할 수 있습니다.
Rauhotz

3
약점은 VS에게 throw 된 예외에서 중단하도록 지시하거나 범위를 좁히고 특정 예외를 선택할 수 있습니다. VS2008에는 디버그중인 메뉴 항목이 있습니다 (찾으려면 도구 모음을 사용자 지정해야합니다). Called Exceptions
JoshBerke

"코드 냄새"예제는 단순한 형태에서도 확실한 부작용이 있습니다. 경우 // do something어떤 포함 try/finally발생 지점 주변 블록의 finally블록은 이전에 실행할 catch블록. 이 없으면 try/catch예외가 finally실행되는 블록 없이 스택의 맨 위로 올라갑니다 . 이를 통해 최상위 수준 처리기가 finally블록 을 실행할지 여부를 결정할 수 있습니다.
Daniel Earwicker

9

주제에 대한 또 다른 좋은 출처를 추천하고 싶습니다. Java의 Checked Exception 주제에 대해 각각 C # 및 Java, Anders Hejlsberg 및 James Gosling의 발명가와의 인터뷰입니다.

실패 및 예외

페이지 하단에는 훌륭한 리소스도 있습니다.

나는 Anders Hejlsberg와 당신에게 동의하는 경향이 있습니다.

Bill Venners : 확인 된 예외와 관련하여 확장 성 및 버전 관리 문제를 언급 하셨습니다 . 이 두 가지 문제가 의미하는 바를 명확히 할 수 있습니까?

Anders Hejlsberg : 버전 관리부터 시작해 보겠습니다. 문제를 쉽게 볼 수 있기 때문입니다. 예외 A, B, C를 던진다 고 선언하는 foo 메서드를 생성했다고 가정 해 보겠습니다. foo 버전 2에서는 여러 기능을 추가하고 싶습니다. 이제 foo는 예외 D를 던질 수 있습니다. 해당 메서드의 throws 절에 D를 추가합니다. 해당 메서드의 기존 호출자는 해당 예외를 거의 확실히 처리하지 않기 때문입니다.

새 버전에서 throws 절에 새 예외를 추가하면 클라이언트 코드가 손상됩니다. 인터페이스에 메소드를 추가하는 것과 같습니다. 인터페이스를 게시 한 후에는 모든 구현에 다음 버전에 추가하려는 메서드가있을 수 있으므로 모든 실용적인 목적을 위해 변경할 수 없습니다. 따라서 대신 새 인터페이스를 만들어야합니다. 예외와 유사하게, 더 많은 예외를 발생시키는 foo2라는 완전히 새로운 메서드를 생성하거나 새 foo에서 예외 D를 포착하고 D를 A, B 또는 C로 변환해야합니다.

Bill Venners :하지만 검사 된 예외가없는 언어에서도 어쨌든 그 경우에 그들의 코드를 깨뜨리지 않습니까? foo의 새 버전이 클라이언트가 처리에 대해 생각해야하는 새로운 예외를 던질 경우, 코드를 작성할 때 예외를 예상하지 않았다는 사실로 인해 코드가 깨지지 않습니까?

Anders Hejlsberg : 아니요. 많은 경우 사람들이 신경 쓰지 않기 때문입니다. 그들은 이러한 예외를 처리하지 않을 것입니다. 메시지 루프 주변에는 하위 수준의 예외 처리기가 있습니다. 그 핸들러는 무엇이 잘못되었는지를 알려주는 대화를 불러와 계속할 것입니다. 프로그래머는 어디에서나 try finally를 작성하여 코드를 보호하므로 예외가 발생하면 올바르게 되돌릴 수 있지만 실제로는 예외 처리에 관심이 없습니다.

throws 절은 최소한 Java에서 구현 된 방식으로 반드시 예외를 처리하도록 강요하지는 않지만 예외를 처리하지 않으면 통과 할 수있는 예외를 정확하게 인식해야합니다. 선언 된 예외를 포착하거나이를 자신의 throws 절에 넣어야합니다. 이 요구 사항을 해결하기 위해 사람들은 우스꽝스러운 일을합니다. 예를 들어, 모든 메소드를 "예외 발생"으로 장식합니다. 그것은 기능을 완전히 무너 뜨리고 프로그래머가 더 엉뚱한 멍청이를 작성하도록 만들었습니다. 그것은 누구에게도 도움이되지 않습니다.

편집 : 대화에 대한 자세한 내용 추가


감사합니다! 귀하의 답변에 대한 정보로 내 질문을 업데이트했습니다!
AtariPete

Hejlsberg 씨가 Pokemon 예외 처리를 정당화하는 것처럼 들립니다. Java 및 C #에서 예외 설계의 큰 문제 중 하나는 예외 유형 으로 너무 많은 정보를 인코딩 하는 반면 예외 인스턴스에 정보를 저장해야하는 경우 일관된 방식으로 사용할 수 없다는 것입니다. 예외는 표시된 모든 비정상 상태가 해결 될 때까지 호출 스택에 전파되어야합니다. 안타깝게도 예외 유형은 인식 되더라도 상황이 해결되었는지 여부를 나타내는 데 거의 영향을주지 않습니다. 예외가 인식되지 않는 경우 ...
supercat 2013 년

... 상황은 더 나쁩니다. 코드가 호출 FetchData되어 예기치 않은 유형의 예외가 발생하면 해당 예외가 단순히 데이터를 사용할 수 없음을 의미하는지 여부를 알 수있는 방법이 없습니다 (이 경우 코드없이 가져올 수있는 기능이 데이터를 "해결"할 수 있음). CPU가 불타고 있고 시스템이 첫 번째 기회에 "안전 종료"를 수행해야하는지 여부. Hejlsberg 씨가 코드가 전자를 가정해야한다고 제안한 것처럼 들립니다. 아마도 그것은 기존의 예외 계층 구조를 고려할 때 가능한 최선의 전략이지만 그럼에도 불구하고 이상하게 보입니다.
supercat 2013 년

거의 모든 것이 예외를 던질 수 있기 때문에 throws Exceptin이 우스꽝 스럽다는 데 동의합니다. 여러분은 이것이 일어날 수 있다고 가정해야합니다. 그러나 throws A, B, C와 같은 예외를 지정하면 주석 일 뿐이며 Comment 블록처럼 사용해야합니다. 내 기능의 클라이언트, 여기에 팁이 있습니다. A, B, C를 처리하고 싶을 수도 있습니다. 나를 사용할 때 이러한 오류가 발생할 가능성이 있기 때문입니다. 미래에 D를 추가하면 처리되지 않는 경우 큰 문제는 아니지만 새로운 문서를 추가하는 것과 같습니다. 그런데 이제 D를 잡는 것도 유용 할 것입니다.
Didier A.

8

확인 된 예외는 일반적으로 논란의 여지가있는 문제이며, 특히 Java에서 (나중에 이에 찬성하고 반대하는 사람들에 대한 몇 가지 예를 찾으려고 노력할 것입니다).

경험상 예외 처리는 특별한 순서없이 이러한 지침을 중심으로 이루어져야합니다.

  • 유지 보수성을 위해 항상 예외를 기록하여 버그를보기 시작할 때 로그가 버그가 시작되었을 가능성이있는 위치를 가리키는 데 도움이 될 것입니다. 절대 떠나지 마십시오. printStackTrace()사용자 중 한 명이 결국 스택 트레이스 중 하나를 얻게 되며이를 처리 할 방법에 대한 지식전혀 없습니다.
  • 처리 할 수있는 예외 만 잡아서 처리하세요 . 스택 위로 던지지 마세요.
  • 항상 특정 예외 클래스를 포착하고 일반적으로 type을 포착해서는 안됩니다 Exception. 그렇지 않으면 중요한 예외를 삼킬 가능성이 매우 높습니다.
  • 절대 (절대) Errors를 잡아라 !! 의미 : 절대 캐치 Throwable이야Error의 후자의 서브 클래스입니다. Errors는 처리 할 수없는 문제 (예 : OutOfMemory또는 기타 JVM 문제)입니다.

특정 경우와 관련하여 메서드를 호출하는 모든 클라이언트가 적절한 반환 값을 수신하는지 확인하십시오. 뭔가 실패하면 부울 반환 메서드가 false를 반환 할 수 있지만 해당 메서드를 호출하는 장소에서이를 처리 할 수 ​​있는지 확인하십시오.


확인 된 예외는 예외가 없기 때문에 C #에서 문제가되지 않습니다.
cletus

3
Imho, 때로는 오류를 포착하는 것이 좋습니다. 저는 제가 작성한 매우 메모리 집약적 인 Java 앱을 사용합니다. 나는 OutOfMemory-Ex를 잡았고 사용자에게 메모리가 부족하다는 메시지를 보여 주었다. 그는 다른 프로그램을 종료하고 더 많은 힙 공간을 할당하여 jvm을 시작하는 방법을 알려 줬다. 도움이되었다고 생각합니다.
Lena Schimmel

5

처리 할 수있는 예외 만 포착해야합니다. 예를 들어 네트워크를 통해 읽기를 처리하고 연결 시간이 초과되고 예외가 발생하면 다시 시도 할 수 있습니다. 그러나 네트워크를 통해 읽을 때 IndexOutOfBounds 예외가 발생하면 원인을 알지 못하기 때문에 실제로 처리 할 수 ​​없습니다. false, -1 또는 null을 반환하려면 특정 예외에 대한 것인지 확인하십시오. 예외가 발생하면 힙이 메모리가 부족할 때 네트워크 읽기에서 false를 반환하는 라이브러리를 사용하고 싶지 않습니다.


3

예외는 정상적인 프로그램 실행의 일부가 아닌 오류입니다. 프로그램의 기능과 용도 (예 : 워드 프로세서 대 심장 모니터)에 따라 예외가 발생할 때 다른 작업을 수행하고 싶을 것입니다. 나는 정상적인 실행의 일부로 예외를 사용하는 코드로 작업했으며 확실히 코드 냄새입니다.

전의.

try
{
   sendMessage();

   if(message == success)
   {
       doStuff();
   }
   else if(message == failed)
   {
       throw;
   }
}
catch(Exception)
{
    logAndRecover();
}

이 코드는 나를 바보로 만듭니다. IMO는 중요한 프로그램이 아닌 한 예외에서 복구해서는 안됩니다. 예외를 던지면 나쁜 일이 발생합니다.


2

위의 모든 것이 합리적으로 보이며 종종 직장에 정책이있을 수 있습니다. 우리 대신 예외 유형을 정의했습니다 : SystemException(선택 안 함) 및 ApplicationException(선택).

우리는 SystemExceptions가 복구 될 가능성이 낮으며 맨 위에서 한 번 처리 될 것이라는 데 동의했습니다 . 더 컨텍스트를 제공하기 위해, 우리 SystemException의 그들이 발생한 위치를 예를 들면, 표시하기 위해 exteneded있다 RepositoryException, ServiceEception

ApplicationExceptions는 다음과 같은 비즈니스 의미를 가질 수 있으며 InsufficientFundsException클라이언트 코드에 의해 처리되어야합니다.

구체적인 예를 들어 Witohut은 구현에 대해 설명하기 어렵지만 반환 코드를 사용하지 않을 것입니다. 유지 관리 문제입니다. 예외를 삼킬 수도 있지만 이유를 결정하고 항상 이벤트와 스택 추적을 기록해야합니다. 마지막으로, 귀하의 메서드에는 다른 처리가 없기 때문에 상당히 중복되므로 (캡슐화 제외?) doactualStuffOnObject(p_jsonObject);부울을 반환 할 수 있습니다!


1

약간의 생각과 코드를 살펴본 후 단순히 예외를 부울로 다시 던지는 것처럼 보입니다. 메서드가이 예외를 통과하도록 허용하고 (잡을 필요도 없음) 호출자에서 처리 할 수 ​​있습니다. 그것이 중요한 장소이기 때문입니다. 예외로 인해 호출자가이 함수를 재 시도하는 경우 호출자가 예외를 포착해야합니다.

때때로 발생하는 예외가 호출자에게 의미가 없을 수 있습니다 (예 : 네트워크 예외).이 경우 도메인 특정 예외로 래핑해야합니다.

반면에 예외가 프로그램에서 복구 할 수없는 오류를 나타내는 경우 (예 :이 예외의 최종 결과는 프로그램 종료가 됨) 개인적으로이를 포착하고 런타임 예외를 발생시켜이를 명시 적으로 만들고 싶습니다.


1

예제에서 코드 패턴을 사용하려면 TryDoSomething이라고 부르고 특정 예외 만 포착합니다.

또한 진단 목적으로 예외를 로깅 할 때 예외 필터 사용을 고려하십시오 . VB에는 예외 필터에 대한 언어 지원이 있습니다. Greggm의 블로그에 대한 링크에는 C #에서 사용할 수있는 구현이 있습니다. 예외 필터는 catch 및 rethrow보다 디버깅 가능성에 대해 더 나은 속성을 가지고 있습니다. 특히 필터에 문제를 기록하고 예외가 계속 전파되도록 할 수 있습니다. 이 방법을 사용하면 JIT (Just in Time) 디버거를 연결하여 전체 원본 스택을 가질 수 있습니다. 다시 던지면 다시 던진 지점에서 스택이 잘립니다.

TryXXXX가 의미가있는 경우는 정말 예외적이지 않거나 함수를 호출하지 않고 테스트하기가 간단한 경우를 던지는 타사 함수를 래핑하는 경우입니다. 예는 다음과 같습니다.

// throws NumberNotHexidecimalException
int ParseHexidecimal(string numberToParse); 

bool TryParseHexidecimal(string numberToParse, out int parsedInt)
{
     try
     {
         parsedInt = ParseHexidecimal(numberToParse);
         return true;
     }
     catch(NumberNotHexidecimalException ex)
     {
         parsedInt = 0;
         return false;
     }
     catch(Exception ex)
     {
         // Implement the error policy for unexpected exceptions:
         // log a callstack, assert if a debugger is attached etc.
         LogRetailAssert(ex);
         // rethrow the exception
         // The downside is that a JIT debugger will have the next
         // line as the place that threw the exception, rather than
         // the original location further down the stack.
         throw;
         // A better practice is to use an exception filter here.
         // see the link to Exception Filter Inject above
         // http://code.msdn.microsoft.com/ExceptionFilterInjct
     }
}

TryXXX와 같은 패턴을 사용하는지 여부는 스타일 문제에 가깝습니다. 모든 예외를 잡아서 삼키는 문제는 스타일 문제가 아닙니다. 예상치 못한 예외가 전파 될 수 있는지 확인하십시오!


.net의 TryXXX 패턴을 좋아합니다.
JoshBerke

1

사용중인 언어에 대한 표준 라이브러리에서 단서를 가져 오는 것이 좋습니다. C #에 대해서는 말할 수 없지만 Java를 살펴 보겠습니다.

예를 들어 java.lang.reflect.Array에는 정적 set메소드가 있습니다.

static void set(Object array, int index, Object value);

C 방식은

static int set(Object array, int index, Object value);

... 반환 값이 성공 표시기입니다. 그러나 당신은 더 이상 C 세계에 있지 않습니다.

예외를 수용 한 후에는 오류 처리 코드를 핵심 논리에서 멀어지게하여 코드를 더 간단하고 명확하게 만들 수 있습니다. 단일 try블록 에 많은 문을 포함하는 것을 목표로 합니다.

다른 사람들이 언급했듯이-포착하는 예외의 종류에 대해 가능한 한 구체적이어야합니다.


이것은 매우 유효한 의견이며, 언어를 존중하고 전통적으로 그러한 문제를 어떻게 관리하는지에 유의하십시오. Java 세계에 C 사고 방식을 도입하지 마십시오.
AtariPete

0

예외를 잡아서 false를 반환하려면 매우 구체적인 예외 여야합니다. 당신은 그렇게하지 않고 그들 모두를 잡아서 거짓을 반환하고 있습니다. MyCarIsOnFireException이 발생하면 즉시 알고 싶습니다! 내가 신경 쓰지 않을 나머지 예외. 따라서 일부 예외에 대해 "whoa whoa something is wrong"이라고 말하는 예외 처리기 스택이 있어야합니다 (다시 던지거나 발생한 일을 더 잘 설명하는 새 예외를 잡아서 다시 던짐). 다른 사람에게는 false를 반환합니다.

이것이 출시 할 제품인 경우 해당 예외 사항을 어딘가에 기록해야하며 향후 조정하는 데 도움이 될 것입니다.

편집 : 모든 것을 try / catch로 감싸는 질문에 대해서는 대답이 '예'라고 생각합니다. 예외는 코드에서 매우 드물 어서 catch 블록의 코드가 거의 실행되지 않아 성능에 전혀 영향을주지 않습니다. 예외는 상태 시스템이 중단되어 무엇을해야할지 모르는 상태 여야합니다. 적어도 그 당시에 무슨 일이 일어 났는지 설명하고 그 안에 잡힌 예외가있는 예외를 다시 던져라. "doSomeStuff () 메서드의 예외"는 휴가 중 (또는 새 직장에있는 동안) 문제가 발생한 이유를 알아야하는 사람에게는별로 도움이되지 않습니다.


예외 블록의 설정이 ... 너무 비용 잊지 마세요
devstuff

0

내 전략 :

원래 함수가 void 를 반환하면 bool 을 반환하도록 변경합니다 . 예외 / 오류가 발생 하면 false를 반환 하고 모든 것이 정상 이면 true를 반환 합니다 .

함수가 무언가를 반환해야하는 경우 예외 / 오류가 발생했을 때 null 을 반환하고 그렇지 않으면 반환 가능한 항목을 반환합니다.

bool 대신 오류 설명이 포함 된 문자열 이 반환 될 수 있습니다.

반환하기 전에 모든 경우에 오류를 기록합니다.


0

여기에 몇 가지 훌륭한 답변이 있습니다. 나는 당신이 게시 한 것과 같은 것을 끝내면 적어도 스택 추적보다 더 많은 것을 인쇄한다고 덧붙이고 싶습니다. 그 당시에하고 있던 일과 Ex.getMessage ()를 말하여 개발자에게 싸울 기회를주세요.


전적으로 동의합니다. 나는 Ex.printStackTrace (); 내가 캐치에서하고 있던 일의 예로서 (즉, 다시 던지지 않음).
AtariPete

0

try / catch 블록은 첫 번째 (메인) 집합 위에 포함 된 두 번째 논리 집합을 형성합니다. 따라서 읽을 수없고 디버그하기 어려운 스파게티 코드를 제거하는 좋은 방법입니다.

그래도 합리적으로 사용하면 가독성이 뛰어나지 만 두 가지 간단한 규칙을 따라야합니다.

  • 라이브러리 처리 문제를 파악하고 주요 논리 흐름으로 다시 스트리밍하기 위해 저수준에서 사용합니다. 우리가 원하는 대부분의 오류 처리는 데이터 자체의 일부로서 코드 자체에서 발생해야합니다. 반환되는 데이터가 특별하지 않은데 왜 특별한 조건을 만드나요?

  • 상위 수준에서 하나의 큰 처리기를 사용하여 하위 수준에서 잡히지 않은 코드에서 발생하는 이상한 조건 중 일부 또는 전부를 관리합니다. 오류 (로그, 재시작, 복구 등)에 대해 유용한 작업을 수행하십시오.

이 두 가지 유형의 오류 처리를 제외하고 중간에있는 나머지 코드는 모두 자유롭고 try / catch 코드 및 오류 개체가 없어야합니다. 이렇게하면 어디서 사용하거나 무엇을 사용하든 간단하고 예상대로 작동합니다.

폴.


0

답변에 조금 늦었을 수 있지만 오류 처리는 시간이 지남에 따라 항상 변경하고 발전 할 수있는 것입니다. 이 주제에 대해 더 많은 것을 읽고 싶다면 새 블로그에 글을 썼습니다. http://taoofdevelopment.wordpress.com

즐거운 코딩입니다.

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