프로그래밍의 에러 종류
•
컴파일 에러 (compile-time error) : 컴파일 시에 발생하는 에러
•
런타임 에러 (runtime error) : 실행 시에 발생하는 에러
•
논리적 에러 (logical error) : 실행은 되지만 의도와 다르게 동작
논리적 에러
•
프로그램은 정상적으로 동작하는 것처럼 보이지만, 실행 결과가 개발자의 의도와 다르게 하고자 했던 로직이 정상적으로 실행되지 않는 에러를 말한다.
•
해당 에러는 프로그램은 정상적인 동작으로 인식하기 때문에 별 다른 에러를 뱉지 않는다.
하지만 해당 에러는 어떠한 오류도 내지 않기 때문에, 그 어떠한 에러보다 개발자들이 싫어하는 오류이다.
주의점!!
•
논리적 에러는 향후 취약점으로 연결될 수 있다.
•
의도와 다르게 동작하기 때문에 서비스 가용성에 문제가 생길 가능성이 크다.
•
해당 에러를 잡기 위해서는 모든 코드를 디버깅 해봐야 하는 불상사가 생길 수 있다…..
컴파일 에러
•
컴파일 에러는 프로그램 코드를 컴파일할 때 발생되는 에러로 심각하게 볼 필요 없이 흔하게 볼 수 있는 에러이다.
•
Syntax error와 같은 이유로 IDE 상에 나타나는 빨간 줄 역시 컴파일 에러에 해당한다.
정확히는 Java로 따지자면, Javac를 통해 컴파일하는 과정에서 생기는 에러를 뱉는 것이지만 IDE 상에서는 문법 오류를 빠르게 알려주기 때문에 수정하면 된다!!
런타임 에러
•
컴파일 에러를 꼼꼼하게 잡아 컴파일에는 문제가 없더라도, 프로그램 실행 중에 에러가 발생해서 잘못된 결과를 얻거나, 혹은 외부적인 요인으로 기계적 결함으로 프로그램이 비정상적으로 종료될 수 있다.
•
대체로 개발 시 설계 미숙(논리적)으로 발생하는 에러가 대부분이며, 런타임 에러 발생 시 프로그래머가 역추적해서 원인 확인해야 한다.
스프링이 제공하는 선언적 트랜잭션(@Transactional)안에서 예외 발생 시 체크 예외는 롤백이 되지 않고, 언체크 예외는 롤백된다.
Java에서는 런타임 에러를 Error와 Exception으로 구분해 두었다.
•
에러(error) : 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
→ 메모리 부족(OutOfMemoryError)이나 스택오버플로우(StackOverflowError)와 같이 일단 발생하면 복구할 수 없는 심각한 오류이고 예측이 불가능한 녀석이다. 즉, 에러는 JVM 실행에 문제가 생긴 것이므로 개발자가 대처할 방법이 없다.
•
예외(exception) : 프로그램 코드에 의해서 수습될 수 있는 미약한 오류
→ 즉 알고리즘 오류로 Exception 예외가 계속 발생한다고 해도 Error 처럼 프로그램이 죽거나 그럴경우는 적기 때문
Java 에러 & 예외
TODO
•
위에서 말한 것과 같이 에러는 심각한 오류, 예외는 미약한 오류이지만, 예외를 가볍게 보고 넘어가면 안된다.
→ 비정상적 종료, 비정상 동작 등이 발생할 수 있기 때문
Java의 Exception을 Handling하기 위해 try catch 구문을 통해 Exception을 받고, 예외상황을 처리해야만 한다.
•
아래는 자바의 에러와 예외의 상관관계이다.
•
각종 Error와 Exception은 Java의 Throwable Class를 상속받아 만들어지며 실제로 많은 Error와 Exception이 Throwable 객체의 Subclass로 존재한다.
•
Throwable 클래스에는 getMessage()와 printStackTrace() 함수가 구현되어 있다.
•
getMessage()
◦
해당 throwable 객체에 대한 자세한 내용을 문자열로 반환
•
printStackTrace()
◦
해당 throwable 객체와 표준 오류 스트림(standard error stream)에서 해당 객체의 스택 트레이스(Stack Trace)를 출력한다.
◦
Stack Trace
▪
프로그램의 실행 과정에서 호출된 메서드들의 순서와 위치 정보를 나타낸 것
여러가지 Error 종류와 Exception 종류들 [출처 : https://inpa.tistory.com/entry/JAVA--에러Error-와-예외-클래스Exception--총정리 [Inpa Dev :티스토리]]
•
Error Class는 외부 요인으로 발생하는 것으로 개발자가 대처할 수 없기 때문에 우리와 같은 개발자가 집중해야할 곳은 Exception이다.
Exception 클래스
•
Exception Class 안에도 컴파일 에러와 런타임 에러가 모두 존재한다.
•
Exception Class 안에 있는 Exception 중 RunTimeException을 제외하고는 모두가 CompileException로 나뉜다.
대표적 예외 클래스 종류
예외 타입 | 설명 |
ArithmeticException | 어떠한 수를 0으로 나누는것과 같이 비정상 계산 중발생 |
NullPointException | Null 객체 참조시 발생 |
IllegalArgumentException | 메소드의 전달 인자값이 잘못된 경우 발생 |
IllegalStateException | 객체의 상태가 메소드 호출에는 부적합할 경우 발생 |
IndexOutOfBoundsException | index 값이 범위를 넘어갈 경우 발생 |
UnsupportedOperationException | 객체가 메소드를 지원하지 않는 경우 발생 |
SecurityException | 보안 위반 발생 시 보안 관리 프로그램에서 발생 |
ProviderException | 구성 공급자 오류시 발생 |
NoSuchElementException | 구성 공급자 그 이상 없는 경우 발생 |
ArrayStoreException | 객체 배열에 잘못된 객체 유형 저장시 발생 |
ClassCastException | 클래스 간의 형 변환 오류시 발생 |
EmptyStackException | 스택이 비어있는데 요소를 제거하려고 할 시 발생 |
Checked / Unchecked Exception
•
간단하게 Checked Exception == Compile Exception, Unchecked Exception == RunTime Exception 이라고 생각하면 된다.
•
하지만, 코드적 관점에서 예외처리 동작을 필수로 지정해야 하는 지, 말아도 되는지의 유무에 따라 나뉜다.
Checked Exception Handling 방법
1.
try - catch 구문
public String makeTokenString(User user) {
JwtToken jwtToken = makeToken(user);
try {
return gsonUtil.deserialize(jwtToken);
} catch (Exception e) {
log.warn("Fail to makeTokenString. ({}) ({})", e.getCause(), e.getMessage());
return null;
}
}
Java
복사
2.
throws 이용
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
}
Java
복사
3.
Checked. Exception → Unchecked Exception 변환
•
chained exception을 이용해 IOException과 같은 Checked Exception을 RuntimeException으로 감싸줘 Unchecked Exception으로 변환한다.
class MyCheckedException extends Exception { ... } // checked excpetion
public class Main {
public static void main(String[] args) {
install();
}
public static void install() {
throw new RuntimeException(new IOException("설치할 공간이 부족합니다."));
// Checked 예외인 IOException을 Unchecked 예외인 RuntimeException으로 감싸 Unchecked 예외로 변신 시킨다
}
}
Java
복사
4.
try-with-resources
•
try 블록에서 사용할 resource를 선언
•
finally 블록에서 자원 반환 코드를 작성하지 않아도 자원(Resource)을 자동으로 반환하기 위해 사용
•
자원(Resource)
◦
java.lang.AutoClosable 또는 java.io.Closable을 구현한 객체
public static void main(String args[]) {
try (
FileInputStream fis = new FileInputStream("file.txt");
BufferedInputStream bis = new BufferedInputStream(fis)
) {
//do something
} catch (IOException e) {
// 에러처리
}
}
Java
복사