프로그램을 작성하면서, 각양각색의 이유로 오류가 발생할 수 있다. 하지만 다들 알다시피, 파이썬 프로그램 실행 중 오류가 생기면 즉시 프로그램이 종료된다!
이는 실제 서비스하는 프로그램에서 큰 문제가 될 수 있다.
(만약에 은행 서버에서 sql 한 번 잘못 날렸다가 빈 값 받아오게 되면 은행 서버가 다 다운되는 대참사를 목격할 수 있게 된다)
즉, 오류가 발생하면 프로그램을 종료하지 않고 그 이후 어떤 행위를 취할 것인지를 설정해야하는데, 이를 예외처리라 한다.
또, 보안 상 예외 메세지를 사용자에게 노출하지 않기 위해서도 사용한다.
예외처리는 주로 try,catch,finally를 이용한다.
(finally는 오류가 나도, 정상적으로 실행해도 마지막으로 꼭 실행할 구문이다.)
컴파일 시 발생하는 에러임. 웬만하면 IDE에서 잡아주고, 고치지 않는 이상 실행이 안된다. 개발자가 인식하기 편하다.
실행하고 나서 발생하는 에러임. 컴파일러는 실행 전에 이러한 오류를 알 수 없음. 자바에서는 이런 런타임 에러를 예외,에러 라는 두 종류로 구분함

try 내의 구문을 실행하다가 오류가 나면 except 구문으로 이동한다. 이 때, try내에서 발생한 오류에 대해 except구문으로 가져오고 싶다면, 앞에 except를 넣는다. (주로 except Exception as e: 로 붙여 쓴다.)
try:
실행 시도 할 구문
except (에러 타입, 디폴트값은 Except):
명시된 타입의 에러가 발생했을 때 실행한 구문
else:
예외가 발생하지 않았을 때 처리하는 수행 코드
finally:
예외 여부 발생 상관 없이 항상 실행하는 수행 코드
assert는 주로 함수 내부의 값이 잘못되면 실행한다.
def add(x,y):
#x,y가 정수로만 받아야 한다.
assert str(type(x))!="int" or str(type(y))!="int" "x or y is not integer"
return x+y
assert가 조건을 만족했을 경우 오류를 발생시키는 것이라면,
raise는 아무런 조건 없이 오류를 발생하는 경우다.
raise 에러객체
try 내에서 raise를 만나면, 뒤에 명시한 에러가 일어난다.
try:
x = int(input('7의 배수를 입력하세요'))
if (x%7!=0):
raise Exception ('7의 배수가 아닙니다.')
print(x)
except Exception as e:
print(e)
참고로 raise가 except 구문 내에서 있다면, 현재 상위에서 발생했던 예외를 다시 발생시킨다.
-> 따라서 상위에서 따로 예외처리가 또다시 필요하다.
def multiple_seven():
try:
x = int(input('7의 배수 입력 : '))
if (x % 7) != 0:
raise Exception('7의 배수가 아님.')
print(x)
except Exception as e:
print(f'in 예외 발생 : {e}')
raise # 현재 상위에서 발생한 예외를 한번 더 일으킨다
try:
multiple_seven()
except Exception as e:
print(f'out 예외 발생 : {e}')
# 이처럼 상위 단계에서 한 번 더 예외 처리가 필요하다!!!
예외가 생긴 그 부분에서 예외가 발생한 후 상황을 처리하는 것이 아니라,
부모 클래스에 해당 예외를 떠넘긴다.

만약에 try가 성공적으로 실행되었을 때, 실행 후 else 뒤에 오는 구문을 실행하도록 한다.
try 안 구문이 오류가 나던, 나지 않던 마지막에 실행되어져야 하는 구문이다.

예외처리를하면서, SQL쿼리를 잘못 입력한 경우, SQLException이발생하도록 따로 에러 타입을 명시해줬다.
이는 체크 예외이기 때문에, 에러 처리할 수 있는 컴포넌트(예를 들어 서블릿 오류 페이지)가 받을 수 있을 때 까지 상위 컴포넌트에게 같은 타입의 예외를 계속 던져야한다.

하지만 언체크예외는 (RuntimeSQLException)모다? 필수로 안 던져도 된다!
처음에 에러가 발생한 컴포넌트애서 예외를 발생시키고, 예외 처리 컴포넌트에서만 잡아내면 된다.
하지만 이는 SQL을 이용할 때만의 이야기다. 만약에 Sql이 아닌 JDBC로 DB를 바꾸고자 하는 경우, 또 일일이 오류 타입을바꿔줘야한다. 이는 김영한 선생님께서 그토록 싫어하시는 의존관계가 형성된다는 이야기다.
우리는 이를 인터페이스로 해결할 것이다. 늘 그랬듯이,
public class MyDbException extends RuntimeException{
public MyDbException() {
}
public MyDbException(String message) {
super(message);
}
public MyDbException(String message, Throwable cause) {
super(message, cause);
}
public MyDbException(Throwable cause) {
super(cause);
}
}
그 다음 RuntimeSQLException이 들어가는 자리에 그냥 MyDBException을 넣어주면 되는 것이다
** 대부분의 경우 언체크 예외를 사용하고, 정말 어쩔 수 없이 '이 타입의 오류가 발생해!!!'라는걸 알려야 한다면, 체크 예외를 사용할 것