try / catch / throw와 try / catch (e) / throw e의 차이점
차이점은 무엇입니까
try { }
catch
{ throw; }
과
try { }
catch(Exception e)
{ throw e;}
?
그리고 언제 둘 중 하나를 사용해야합니까?
구조
try { ... }
catch () { ... } /* You can even omit the () here */
try { ... }
catch (Exception e) { ... }
둘 다 블록 내부에서 발생하는 모든 예외 를 포착한다는 점에서 비슷 합니다 try
(이를 사용하여 예외를 기록하는 데 사용하지 않는 한 피해야합니다 ). 이제 이것들을보세요 :
try { ... }
catch ()
{
/* ... */
throw;
}
try { ... }
catch (Exception e)
{
/* ... */
throw;
}
try { ... }
catch (Exception e)
{
/* ... */
throw e;
}
첫 번째와 두 번째 try-catch 블록은 똑같습니다. 단순히 현재 예외를 다시 던지고 해당 예외가 "소스"와 스택 추적을 유지합니다.
세 번째 try-catch 블록은 다릅니다. 예외가 발생하면 소스와 스택 추적이 변경되어 throw e
해당 try-catch 블록을 포함하는 메서드의 바로 그 줄에서이 메서드에서 예외가 throw 된 것처럼 보입니다 .
어느 것을 사용해야합니까? 각 경우에 따라 다릅니다.
데이터베이스에 유지 Person
하는 .Save()
메서드 가있는 클래스 가 있다고 가정 해 보겠습니다 . 애플리케이션이 Person.Save()
어딘가 에서 메서드를 실행한다고 가정 해 보겠습니다 . DB가 Person 저장을 거부 .Save()
하면 예외가 발생합니다. throw
또는 throw e
이 경우에 사용해야합니까 ? 음, 상황에 따라 다릅니다.
내가 선호하는 것은 다음과 같습니다.
try {
/* ... */
person.Save();
}
catch(DBException e) {
throw new InvalidPersonException(
"The person has an invalid state and could not be saved!",
e);
}
이것은 DBException을 던지는 새로운 예외의 "내부 예외"로 넣어야합니다. 따라서이 InvalidPersonException을 검사 할 때 스택 추적에는 Save 메서드에 대한 정보가 포함되지만 (문제를 해결하는 데 충분할 수 있음) 필요한 경우 원래 예외에 계속 액세스 할 수 있습니다.
As a final remark, when you are expecting an exception, you should really catch that one specific exception, and not a general Exception
, ie, if you are expecting an InvalidPersonException you should prefer:
try { ... }
catch (InvalidPersonException e) { ... }
to
try { ... }
catch (Exception e) { ... }
Good luck!
The first preserves the stack trace while the second resets it. This means that if you use the second approach the stack trace of the exception will always start from this method and you will lose the original exception trace which could be disastrous for someone reading exception logs as he will never find out the original cause of the exception.
The second approach might be useful when you want to add additional information to the stack trace but it is used like this:
try
{
// do something
}
catch (Exception ex)
{
throw new Exception("Additional information...", ex);
}
There's a blog post discussing the differences.
You should use
try { }
catch(Exception e)
{ throw }
if you want to do something with the exception before re-throwing it (logging for example). The lonely throw preserves stack trace.
The difference between a parameterless catch and a catch(Exception e)
is that you get a reference to the exception. From framework version 2 unmanaged exceptions are wrapped in a managed exception, so the parameterless exception is no longer useful for anything.
The difference between throw;
and throw e;
is that the first one is used to rethrow exceptions and the second one is used to throw a newly created exception. If you use the second one to rethrow an exception, it will treat it like a new exception and replace all stack information from where it was originally thrown.
So, you shold not use either of the alternatives in the question. You should not use the parameterless catch, and you should use throw;
to rethrow an exception.
Also, in most cases you should use a more specific exception class than the base class for all exceptions. You should only catch the exceptions that you anticipate.
try {
...
} catch (IOException e) {
...
throw;
}
If you want to add any information when rethrowing the exception, you create a new exception with the original exception as an inner exception to preservere all information:
try {
...
} catch (IOException e) {
...
throw new ApplicationException("Some informative error message", e);
}
'Programming' 카테고리의 다른 글
C #에서 대리자를 언제 사용합니까? (0) | 2020.08.17 |
---|---|
rsync : --size-only와 --ignore-times의 차이 (0) | 2020.08.17 |
sed가 모든 항목을 대체하지 않는 이유는 무엇입니까? (0) | 2020.08.17 |
Android에서 고유 한 장치 하드웨어 ID를 얻는 방법은 무엇입니까? (0) | 2020.08.17 |
NSUserDefaults의 NSMutableArray에 사용자 지정 개체 저장 (0) | 2020.08.17 |