programing tip

언제 RuntimeException을 잡아도 괜찮습니까?

itbloger 2020. 11. 23. 07:52
반응형

언제 RuntimeException을 잡아도 괜찮습니까?


최근 프로젝트에서 테스트 하네스 코드 내에서 RuntimeException을 포착하고 로깅하는 것이 좋습니다. 이 코드는 데이터베이스의 일련의 입력을 처리하며 하나의 입력 (Null 값, 잘못된 인수 등)의 실패로 인해 테스트가 중지되는 것을 원하지 않습니다. 말할 필요도없이 제 제안은 열정적 인 토론을 불러 일으켰습니다.

어떤 종류의 RuntimeException을 잡을 수 있습니까? 그렇다면 RuntimeExceptions를 잡아도 괜찮은 다른 시나리오는 무엇입니까?


당신은 잡을 RuntimeException당신은 그것으로 뭔가를 할 계획 : 어떤 예외를 잡는 것과 같은 이유. 아마도 예외의 원인이 무엇이든 수정할 수 있습니다. 다른 예외 유형으로 다시 던지기를 원할 수도 있습니다.

그러나 예외를 포착하고 무시 하는 것은 매우 나쁜 습관입니다.


RuntimeException을 정정 할 수없는 경우이를 포착하고 싶지 않습니다.

... 개발자의 관점에서만 사실입니다 ....

UI에 도달하기 전에 모든 예외를 포착하고 사용자를 슬프게해야 합니다. 이것은 "가장 높은 수준"에서 더 아래에서 발생한 모든 일을 포착하려는 것을 의미합니다. 그런 다음 사용자에게 문제가 있음을 알리고 동시에 알람 메일을 발송하는 등 개발자에게 알리기위한 조치를 취할 수 있습니다.

이는 기본적으로 예측할 수없는 데이터 / 프로그래밍 오류로 간주되므로 소프트웨어의 향후 릴리스를 개선하는 동시에 사용자를 손으로 잡고 제어 된 방식으로 계속 진행하고자합니다.


RuntimeException은 프로그래머 오류에 사용하기위한 것입니다. 따라서 절대 잡히면 안됩니다. 다음과 같은 몇 가지 경우가 있습니다.

  1. 예외가 발생할 때 제어 할 수없는 타사에서 제공하는 코드를 호출하고 있습니다. 사례별로이를 수행하고 런타임 이외의 예외를 다시 전달할 수 있도록 자체 클래스 내에서 타사 코드 사용을 래핑해야한다고 주장합니다.

  2. 프로그램이 충돌 할 수 없으며 사용자가 볼 수 있도록 스택 추적을 남길 수 없습니다. 이 경우 메인과 모든 스레드 및 이벤트 처리 코드를 돌아야합니다. 이러한 예외가 발생할 때 프로그램이 종료되어야합니다.

귀하의 특정 경우에는 테스트에서 RuntimeExceptions가 발생하는 이유에 대해 의문을 제기해야합니다. 문제를 해결하는 대신 수정해야합니다.

따라서 프로그램 종료를 원할 때만 코드에서 RuntimeExceptions를 throw하도록해야합니다. 로그하고 종료하려는 경우에만 RuntimeExceptions를 포착해야합니다. 이것이 RuntimeExceptions의 의도와 일치하는 것입니다.

사람들이 제공하는 다른 이유 때문에이 토론볼 수 있습니다 . 저는 개인적으로 대답에서 설득력있는 이유를 찾지 못했습니다.


몇 년 전, 우리는 제어 시스템 프레임 워크를 작성했고 에이전트 개체는 런타임 예외를 포착하고 가능한 경우이를 기록하고 계속했습니다.

네, 우리는 프레임 워크 코드에서 OutOfMemory를 포함한 런타임 예외를 포착 했고 (그리고 GC를 강요했고, 그것이 아주 누출 된 코드를 실행하는 것을 얼마나 잘 유지했는지 놀랍습니다.) 우리는 실제 세계와 관련된 매우 수학적 일을하는 코드를 가지고있었습니다. 그리고 때때로 작은 반올림 오류로 인해 Not-A-Number가 들어올 것이고 그것도 잘 대처했습니다.

따라서 프레임 워크에서 / "종료해서는 안 됨"코드에서 정당화 할 수 있다고 생각합니다. 그리고 그것이 작동 할 때 그것은 꽤 멋지다.

코드는 상당히 견고했지만 하드웨어를 실행했으며 하드웨어는 때때로 잘못된 대답을 제공하는 경향이 있습니다.

한 번에 몇 달 동안 사람의 개입없이 실행되도록 설계되었습니다. 우리 테스트에서 매우 잘 작동했습니다.

오류 복구 코드의 일부로 N 분 내에 전원을 끄고 M 분 내에 전원을 켤 수있는 UPS의 기능을 사용하여 전체 건물을 재부팅 할 수 있습니다.

때때로 하드웨어 결함은 전원을 껐다 켜야합니다. :)

내가 기억한다면, 전원주기에 실패한 후 마지막 수단은 소유자에게 이메일을 보내 "내가 직접 고치려고했지만 할 수 없습니다. 문제는 하위 시스템 XYZ에 있습니다"라고 말하고 지원을 요청하는 링크를 포함하는 것이 었습니다. 우리에게 다시 전화하십시오.

슬프게도 프로젝트는 자각되기 전에 통조림되었습니다. :)>


내 코드에서 내 예외의 99 %는 runtime_exception에서 파생됩니다.

예외를 포착하는 이유는 다음과 같습니다.

  • 로그를 잡아 문제를 수정합니다.
  • 로그를 잡아 더 구체적인 예외를 생성하고 던지기
  • 로그를 잡고 다시 던지십시오 .
  • Catch Log 및 Kill 작업 (예외 삭제)
    • 사용자 / 요청 시작 작업이 실패합니다.
      예를 들어 HTTP 요청 핸들러. 나는 서비스를 중단하는 것보다 요청 된 작업을 죽이는 편이 낫다 (가급적이면 핸들러는 500 오류 코드를 반환하기에 충분한 감각을 가지고 있습니다.)
    • 테스트 케이스가 예외와 함께 통과 / 실패했습니다.
    • 메인 스레드에없는 모든 예외.
      예외가 스레드를 이스케이프하도록 허용하는 것은 일반적으로 잘못 문서화되어 있지만 일반적으로 프로그램 종료를 유발합니다 (스택 해제없이).

개인적으로, 저는 항상 모든 RuntimeExceptions 를 잡기를 원한다고 들었습니다 . 그러나 안전 장치를 실행하거나 오류가 발생했음을 사용자에게 알리는 등 예외 에 대해 뭔가를 수행하려고 할 수도 있습니다 .

내가 작업 한 마지막 Java 프로젝트는 최소한 비슷한 접근 방식을 사용했습니다. 최소한 예외를 기록하여 사용자가 버그에 대해 불만을 제기하면 정확히 무슨 일이 발생했는지 확인하고 오류가 발생한 위치를 확인할 수 있습니다.

편집 1 : kdgregory가 말했듯이 잡기와 무시는 두 가지 다른 것입니다. 일반적으로 사람들은 후자에 반대합니다 :-)


우리는 모두 확인 된 예외를 알고 RuntimeExceptions있으며 두 가지 예외 범주입니다. 불행히도 프로그래머가 스스로 아무것도 할 수없는 프로그래밍 조건이기 때문에 검사 ​​된 예외를 처리 (try-catch 또는 throw)하는 것이 항상 권장됩니다. 마찬가지로 FileNotFoundException이 프로그램은 실제로 파일을 읽으려고하면 사용자의 드라이브에 파일을 저장 프로그래머 아니다 1.txt거기에 있어야하는데 f:\문에 사용자를 :

File f11 = new File("f:\\1.txt");
FileInputStream fos = new FileInputStream(f11);

파일이 발견되면 괜찮지 만 다른 경우에 파일이 발견되지 않으면 프로그램이 사용자로부터 0 오류로 다운됩니다. 이 시나리오에서 프로그래머는 잘못한 것이 없습니다. 이것은 프로그램이 계속 실행되기 위해 포착되어야하는 검사 된 예외 일 수 있습니다.

Let me also explain the second scenario with which the concept of RuntimeException will be clear. Consider following code:

int a = {1,2,3,4,5};
System.out.println(a[9]);

This is poor coding which generates the ArrayIndexOutOfBoundsException. Which is an example of RuntimeException. So programmer should not actually handle the exception, let it crash the program, and later fix the logic.


You catch RuntimeException when you want to process it. Maybe you want to rethrow it as a different exception or log it to a file or database, or you want to turn on some exception flag in the return type, etc.


You catch RuntimeExceptions (in any language: unexpected exceptions/“all” exceptions) when your program is doing multiple subtasks and it makes sense to complete every one you can rather than stopping on the first unexpected situation. A test suite is a fine situation to do this — you want to know which of all the tests failed, not just the first test. The key characteristic is that each test is independent of all the others — it doesn't matter whether a previous test doesn't run because the order is not significant anyway.

Another common situation is a server; you don’t want to shut down just because one request was malformed in a way you didn't expect. (Unless it’s really, really important to minimize the chances of inconsistent state.)

In any of these situations, the appropriate thing to do is log/report the exception and continue with the remaining tasks.

One could vaguely generalize to any exception: it is “appropriate to catch” an exception if and only if there is something sensible to do after catching it: how your program should continue.


If a client can reasonably be expected to recover from an exception, make it a checked exception.

If a client cannot do anything to recover from the exception, make it an unchecked exception.

Here's the bottom line guideline.

From Java Docs. Please read this Unchecked Exceptions — The Controversy

참고URL : https://stackoverflow.com/questions/1982533/when-is-it-ok-to-catch-a-runtimeexception

반응형