Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[최유정] 2023 GDSC Spring Advanced Study - 4주차 #25

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions 최유정/4장_예외.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# 예외

### 예외

- Error

`java.lang.Error` 클래스의 서브 클래스

- Exception

`java.lang.Exception` 클래스와 그 서브 클래스로 정의되는 예외들


### 예외 종류

- Checked Exception

`Exception` 클래스의 서브 클래스이면서, `RuntimeException` 클래스를 상속하지 않은 것들

복구될 가능성이 있는 문제 상황

- Unchecked Exception

j`ava.lang.RuntimeException` 클래스를 상속한 예외

ex) NullPointException (런타임 에러)

발생시 복구보다는 빨리 처리하도록


### 예외 처리 방법

- 복구

다른 작업 흐름으로 유도

```jsx
int maxretry = MAX_RETRY;
while(maxretry — > 0) {
try {
... // 예외가 발생할 가능성이 있는 시도
return;
}
catch(SomeException e) {
// 작업 성공
// 로그 출력. 정해진 시간만큼 대기
} finally {
// 리소스 반납. 정리 작업
}
}
throw new RetryFailedException(); // 최대 재시도 횟수를 넘기면 직접 예외 발생
```

- 예외처리 회피

rethrow, 예외처리를 자신이 담당하지 않고 자신이 호출한 쪽으로 던져버린다

```jsx
public void add() throws SQLException {
try {
// JDBC API
}
catch(SQLException e) {
// 로그 출력
throw e;
}
}
```

- 예외 전환

발생한 예외를 그대로 넘기는 것이 아니라, 전환해서 Rethrow

내부에서 발생한 예외를 그대로 던지는 것이 예외상황에 대해 적절한 의미를 부여해주지 못하는 경우에 의미를 분명히 한다.

```jsx
public void add(User user) throws DuplicateUserldException, SQLException {
try {
// ]DBC를 이용해 user 정보를 애에 추가하는 코드 또는
// 그런 기능을 가진 다른 SQLException을 던지는 메소드를 호출하는 코드
}
catch(SQLException e) {
// ErrorCode가 MySQL의 "Duplicate Entry(1062)"이면 예외 전환
if (e.getErrorCode() == MysqlErrorNumbers.ER_DUP_ENTRY)
throw DuplicateUserIdException();
else
throw e; // 그 외의 경우는 SQLException 그대로
}
}
```

```jsx
// case 1
catch(SQLException e) {
...
throw DuplicateUserldException(e);
}

// case 2
catch(SQLException e) {
...
throw DuplicateUserIdException().initCause(e);
}
```


### 예외처리 전략

보편적으로는 **런타임 에러로 wrapping**

대응이 불가능한 체크 예외라면 빨리 런타임 예외로 전환해서 던지는 게 낫다

지금은 (라이브러리들이) '항상' 복구할 수 있는 예외가 아니라면 일단 언체크 예외로 만드는 경향이 있다. 언체크 예외라도 필요하다면 얼마든지 catch 블록으로 잡아서 복구하거나 처리할 수있다

### DAO 인터페이스와 DataAccessException 계층 구조

- DAO 를 인터페이스로 분리

```jsx
public interface UserDao {
public void add(User user) throws PersistentException; // JPA
public void add(User user) throws HibernateException; // Hibernate
public void add(User user) throws JdoException; // JDO
}
```