우아하게 예회 처리하기

박근수·어제
0
post-thumbnail

01. 예외 처리 방식

오류 코드를 리턴하지 말고, 예외를 던저라

* 옛날에는 오류를 나타낼 때 에러코드를 던졌다.
* 하지만 예외를 던지는 것이 명확하고, 처리 흐름이 깔끔해진다.

예외를 던지고, 처리하는 방식

public void send(){
	try{
    	tryTo();
    }catch (Error e){       // 3
    	logger.log(e);
    }
}
private void tryTo() throws Error{ // 2
	.... 
}

private void Handle getHandle(Id id){
	throw new Error("Invalid handle for : " + id.toString()); // 1
}
1. 오류가 발생한 부분에서 예외를 던진다.(별도의 처리가 필요한 예외라면 checked exception으로 던진다.)
2. checked exception에 대한 예외처리를 하지 않는다면 메서드 선언부에 throws를 명시
3. 예외를 처리할 수 있는 곳에서 catch 하여 처리

02. Unckecked Exception 사용

Exception 가계도

Checked vs Unchecked Exception

* Exception을 상속하면 Checked Exception 명시적인 예외처리가 필요 
	Ex) IOException, SQLException

* RuntimeException을 상속하면 Unckecked Exception 명시적인 예외처리 필요
Ex) NullPointException, IllegalArgumentException, IndexOutofBoundException

< Effective Java > Exception에 관한 규약

자바 언어 명세가 요구하는 것은 아니지만, 업계에 널리 펴진 규약으로 
Error 클래스를 상속해 하위 클래스를 만드는 일은 자제하자.

즉, 사용자가 직접 구현하는 unchecked throwable 모두 RuntimeException의 하위 클래스여야 한다.

Exception, RuntimeException, Error를 상속하지 않는 throwable을 만들 수도 있지만, 이러한 throwable은
정상적인 사항보다 나을게 없으면서 API 사용자를 헷갈리게 한다.

03. Exception 잘 쓰기

예외에 메시지를 담아라

예외에 의미있는 정보 담기

* 오류가 발생한 원인과 위치를 찾기 쉽도록, 예외를 던질 때는 전후 상황을 충분히 덧붙인다.
* 실패한 연산 이름과 유형 등 정보를 담아 예외를 던진다.

exception wrapper

예외를 감싸는 클래스를 만든다

* port.open() 시 발생하는 checked exception 들을 감싸도록 port를 가지는 LocalPort 클래스를 만든다.
* port.open() 이 던지는 checked exception들을 하나의 PortDeviceFailure exception으로 감싸서 던진다.

04. 실무 예외 처리 패턴

getOrElse

  • 예외 대신 기본 값을 리턴한다.
    • null이 아닌 기본 값
    • 도메인에 맞는 기본 값

getOrElseThrow

  • null 대신 예외를 던진다.

파라미터의 null 점검

//Bad
public class Metrics{
	public double xProjection(Point p1, Point p2){
    	return p2.x - p1.x) * 1.5;
        //.xProjection(null, new Point(12,13));
        //NullPointException 발생
    }
}
// null을 리턴하는 것도 나쁘지만 null 메서드를 넘기는 것은 더 나쁘다
// null을 메서드의 파라미터로 넣어여하는 API를 사용하는 경우가 아니면 null을 메서드로 넘기면 안 된다.


//Good
public class Metrix{
	public double xProjection(Point p1, Point p2){
    	if(p1 == null || p2 == null){
        	throw InvalidArgumentException("Invalid argument for..");
        }
        return (p2.x - p1. x) * 1.5;
    }
    
}

null을 파라미터로 받지 못하게한다.

public class Metrix{
	public double xProjection(Point p1, Point p2){
    	assers p1 != null : "p1 should not be null";
    	assers p2 != null : "p2 should not be null";
        
        return (p2.x - p1. x) * 1.5;
    }
    
}

05. 오픈소스 속 Exception 살펴보기

apps-android-commons

1. parameter인 bookmark가 null이면 예외를 던지지 않고 false 리턴
2. db 리소스를 처리할 때 checked exception인 RemoteException을 별도로 처리하지 않고 RuntimeException으로 바꿈
3. finally 블록에서 리소스를 close 처리
profile
개발블로그

0개의 댓글