Catch (Exception)가 거의 항상 나쁜 생각 인 이유는 무엇입니까?
왜 catch(Exception)거의 항상 나쁜 생각입니까?
예외를 잡을 때 제대로 처리해야하기 때문 입니다. 그리고 코드에서 모든 종류의 예외를 처리 할 것으로 기대할 수 없습니다. 또한 모든 예외를 포착 할 때 스택에서 상위에있는 코드를 처리 할 수없는 예외가 발생하여 올바르게 처리 할 수 있습니다.
일반적인 원칙은 가능한 가장 구체적인 유형을 잡는 것입니다.
짧은 이야기 : 버그 마스킹이라고합니다. 잘 작동하지 않고 예외를 던지는 코드가 있고 (또는 해당 코드에 잘못된 입력을 전달하는 경우) 가능한 모든 예외를 포착하여 눈을 멀게한다면 실제로 버그를 발견하고 수정하지 못할 것입니다.
제대로 처리 할 수있는 경우에만 예외를 포착해야합니다. 가능한 모든 예외를 적절하게 처리 할 수 없으므로이를 포착해서는 안됩니다. :-)
왜 예외가 발생했는지 알지 못하기 때문에 몇 가지 예외는 OutOfMemoryException 및 이와 유사한 저수준 시스템 예외와 같은 매우 특수한 자동차를 올바르게 처리해야합니다 (가능한 경우).
따라서 예외 만 포착해야합니다.
- 처리 방법을 정확히 알고있는 것 (예 : FileNotFoundException 등)
- 나중에 다시 올릴시기 (예 : 실패 후 정리 수행)
- 예외를 다른 스레드로 전송해야 할 때
필요한 것에 따라 다릅니다. 다른 유형의 예외를 다른 방식으로 처리해야하는 경우 여러 catch 블록을 사용하고 가능한 한 많은 특정 예외를 포착해야합니다.
그러나 때로는 모든 예외를 동일한 방식으로 처리해야 할 수도 있습니다. 이러한 경우 catch (Exception)는 괜찮을 수 있습니다. 예를 들면 :
try
{
DoSomething();
}
catch (Exception e)
{
LogError(e);
ShowErrorMessage(e); // Show "unexpected error ocurred" error message for user.
}
다음 두 가지 용도로 사용할 수 있습니다 catch(Exception).
- 응용 프로그램의 최상위 수준 (사용자에게 돌아 가기 직전). 그렇게하면 적절한 메시지를 제공 할 수 있습니다.
- 이를 사용하여 저수준 예외를 비즈니스 예외로 마스킹합니다.
첫 번째 경우는 자명하지만 두 번째 경우는 다음과 같습니다.
하기:
try {
// xxxx
} catch(Exception e) {
logger.error("Error XXX",e)
}
@dimitarvp가 말한 것처럼 버그 마스킹입니다.
그러나 아래는 다릅니다.
try {
// xxxx
} catch(Exception e) {
throw new BussinessException("Error doing operation XXX",e)
}
이렇게하면 버그를 무시하고 카펫 아래에 숨길 필요가 없습니다. 상위 애플리케이션 계층에 대한보다 설명적인 메시지와 함께 상위 레벨 예외를 제공하고 있습니다.
올바른 계층에서 예외를 관리하는 것도 항상 중요합니다. 하위 수준 예외를 상위 비즈니스 계층으로 에스컬레이션하면 상위 계층에서이를 제대로 관리하는 것이 사실상 불가능합니다.
이 경우 더 나은 컨텍스트와 메시지를 제공하고 세부 사항으로 이동할 수있는 원래 예외도있는 비즈니스 예외로 하위 수준 예외를 마스킹하는 것을 선호합니다.
그렇더라도 더 구체적인 예외를 포착하고 더 나은 처리를 제공 할 수 있다면 반드시 수행해야합니다.
코드 블록에서를 얻을 수있는 경우 SQLException및 a NetworkException를 잡아서 각각에 대해 적절한 메시지와 처리를 제공해야합니다. 그러나 try / catch 블록의 끝에 Exception매핑이 있으면 BussinessException괜찮습니다. 사실, 나는 상위 서비스 계층이 비즈니스 예외 만 던질 때 적절하다고 생각합니다.
@anthares의 답변 외에 :
예외를 잡을 때 제대로 처리해야하기 때문 입니다. 그리고 코드에서 모든 종류의 예외를 처리 할 것으로 기대할 수 없습니다. 또한 모든 예외를 포착 할 때 스택에서 상위에있는 코드를 처리 할 수없는 예외가 발생하여 올바르게 처리 할 수 있습니다.
일반적인 원칙은 가능한 가장 구체적인 유형을 잡는 것입니다.
catch(Exception) 모든 RuntimeException (확인되지 않은 예외)도 포착하므로 나쁜 습관입니다.
이것은 자바에 따라 다를 수 있습니다.
때로는 확인 된 예외를 발생시키는 메서드를 호출해야합니다. 이것이 EJB / 비즈니스 로직 레이어에 있다면 두 가지 선택이 있습니다.
특정 예외 클래스를 잡는다는 것은이 코드가 예외를 처리하는 방법을 볼 때 예외가 발생할 수있는 작업을 다시 분석해야 함을 의미합니다. 종종 "만약 ..."상황에 빠지게되며 예외가 올바르게 처리되는지 확인하는 데 많은 노력이 필요할 수 있습니다.
Re-throwing means that code calling your EJBs will be littered with catching code that will typically not mean anything to the calling class. n.b. throwing checked exceptions from EJB methods will mean that you are responsible for manually rolling back any transactions.
But sometimes it is OK! Like if you have a piece of code that does something 'extra', which you really don't care about, and you don't want it to blow up your application. For example, I worked on a large application recently where our business partners wanted a certain daily transaction to be summarized in a new log file. They explained that the log wasn't all that important to them, and that it did not qualify as a requirement. It was just something extra that would help them make sense of the data being processed. They did not need it, because they could get the information elsewhere. So that is a rare case where it is perfectly fine to catch and swallow exceptions.
I also worked at a company where all Throwables were caught, and then rethrown inside a custom RuntimeException. I would not recommend this approach, but just pointing out that it is done.
Isn't it another valid scenario to ensure that a thread keeps alive catching exception inside it?
Thread shouldRunWhenApplicationRuns = new Thread() {
@Override
public void run() {
try {
// do something that should never end
} catch (Exception ex) {
// log it
}
};
shouldRunWhenApplicationRuns.start();
ReferenceURL : https://stackoverflow.com/questions/2416316/why-is-the-catchexception-almost-always-a-bad-idea
'Program Club' 카테고리의 다른 글
| Python 다중 처리 및 공유 카운터 (0) | 2020.12.30 |
|---|---|
| 현재 활동 바꾸기 (0) | 2020.12.30 |
| 때로는 JSF URL이 * .jsf, 때로는 * .xhtml, 때로는 / faces / *라는 것을 알 수 있습니다. (0) | 2020.12.30 |
| Scala에서 여러 생성자가있는 Java 클래스를 어떻게 하위 클래스로 만들 수 있습니까? (0) | 2020.12.30 |
| Git을 사용하여 자동 병합을 방지하려면 어떻게해야합니까? (0) | 2020.12.30 |