SlideShare a Scribd company logo
1 of 69
About Me
임도형
딴거 재미없어 오직 개발만 하는
삽질 무쟈게 싫어하는.
dh-rim@hanmail.net
예외?
. . .
모든 일에는 예외가 있다.
모든 시스템에는 예측하지 못하는 상황
이 있다.
작업의 절차를 정의하는 프로그래밍에도
예외가 있을 수 밖에 없다.
프로그래밍에서의 예외
입력, 출력 그리고 제 3의 당당한 IO .
예외가 없이는 출력의 특정 값을 사용.
if(read()==-1)
정보가 빈약하다.
입력
출력
예외
예외의 종류?
예측 가능한 예외
예측 가능하지 않은 예외
예측 가능한 예외
예측 가능한 만큼 그 처리 자체가 개발
의 일부이다.
그런 상황을 처리하는 것이 당연하다.
로그인이 실패했다.
DB에 레코드가 없다.
파일을 찾을 수 없다.
예측 가능하지 않은 예외
버그 아니면 시스템 환경에 기인한다.
실시간 처리는 불가능하다. 대신 개선해
야 한다.
예외 처리가 제대로 되지 않으면?
문제가 발생해도 로그를 보지 않는다.
로그가 중복되거나 누락.
로그에 도움되는 내용이 없다.
println(), 혹은 break point에 의지한 디
버깅.
시스템 개선
한번 발생한 예측하지 못하는 상황이 다
시 발생하지 않도록 하는 것.
발생하지 않도록 한다.
발생한다 해도 예측 가능하게 한다.
오로지 로그에 의존한다. 로그는 예외에
의존한다.
잡을 때의 가이드.
먹지 말자.
정보를 누락하지 말자.
GUIDE : 예외를 잡았으면
처리하라.
게으르지 말자.
다음과 같은 코드는 절대 있어선 안 된다.
예외 잡아서 걍 콘솔로 출력하면 될 경우는 거의 없다.
컴파일 된다고 코딩이 끝난 게 아니다.
어찌 처리할 지 모른다면 잡지 말자.
try {
…
} catch(SomeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Anti Patterns
} catch(SomeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 잡았으면 무언가 해야 한다.
잡은 후의 유형
처리하고 예외상황 종료
절대적으로 로그를 남겨야 한다.
다시 던진다.
로그를 위해 잡아서 메시지만을 보고 다시 던진다.
메시지를 변경하는 것은 바람직하지 않다.
새 예외로 던진다.
세세한 예외를 더 추상화된 예외로 던질 경우
이 예외를 받은 쪽에서는 cause 예외만으로는 정보가 부족하
다.
추가적인 상황정보 추가는 필수적이다.
무시한다.
뭘 더 해볼 것이 없는 경우.
이 경우 로그조차 필요 없는 경우이다.
GUIDE : 예외를 처리했으
면 로그를 남겨라.
로그 유형
로그도 없고 처리도 안 함. -> XXX 최악이다.
차라리 안 잡는 것이 낳다.
뭔가 잘못됐다고 리포팅은 되지만, 재현할 방법이
없다.
처리는 했는데 로그가 없다. -> XX 아주 나쁨
예외가 발생한 상황을 먹어버렸다.
시스템 개선할 여지가 없다.
로그 유형
처리도 하고 로그도 있다. : 다양한 경우가 있다.
한심한 로그(“exception occurred”) -> XX
 있으나 마나 한 로그
무심한 로그(“IOException occurred”) -> X
 대충 감은 잡힌다. “2번 째 데이터를 못 받았는데, IOException 발생했다면…”
 언제까지 감으로 일한 텐가
당연한 로그 -> X 좋은 게 아니다.
 예 : “IOException occurred. message=“socket read failed””
 메시지 남기는 것은 기본이다.
친절한 로그 -> O 상황을 알려주어야 한다.
 예 : “second data reading failed. cause=[IOException, message=“socket read
failed.”]”
 어떤 상황인지 알려준다.
충분한 로그 -> OK
 예 : “second data reading failed. cause=[IOException, message=“socket read
failed.”], peer=“10.10.10.13”, port=1234, auth=“base123”, thread=32
Anti Patterns
} catch(SomeException e) {
// do nothing
}
// 차라리 잡지 말아야 한다.
} catch(IOException e) {
doOtherInstead();
}
// 정상처리가 되었지만, 그 상황에 대한 로그는 없다.
} catch(IOException e) {
doOtherInstead();
Log.warn(“exception occurred.”);
}
// 예외가 발생했다는 것 외에는 정보가 없다.
Anti Patterns
} catch(IOException e) {
doOtherInstead();
Log.warn(“IOException occurred.”);
}
// IOException이란 것만 알지 기타 정보가 없다.
} catch(IOException e) {
doOtherInstead();
Log.warn(e.toString());
}
// 예외 클래스와 예외 메시지는 알지만, 상황을 모른다.
// 더욱이 예외의 stack 정보조차 누락되었다.
GUIDE : 원 예외의 정보
누락 금지
정보 누락 금지
예외의 목적이 무엇? : 시스템 개선
절대, 잡은 예외의 정보를 누락하지 말자. 반드
시 cause로 설정하라.
많은 것을 요구하는 것이 아니다. 친절한 메시
지까지는 몰라도 최소한 잡은 예외를 누락하지
말자.
Anti Patterns
catch(SomeEception e) {
throw new OtherException(“blar”);
}
catch(SomeEception e) {
throw new OtherException(“blar. e=“+e);
}
GUIDE : java.lang의 추상
예외로 잡지 말자.
추상 예외로 잡는다면?
코딩하기는 편하다고 착각할 수도 있다.
try – catch 블럭에 어떤 코드를 넣어도 컴파일 된다.
이렇게 잡은 예외의 처리 방법이 오직 한가지라고 확신
하지 못한다면(대부분의 그렇다) 언젠가 세세한 예외로
나누게 될 것이다.
편하게 아니다.
try {
…
} catch(Throwable e){
…
}
Anti Patterns
public void doSomething() throw SomeException {
try {
doIt();
doOther();
doMore();
doAgain();
} catch(Exception e) {
. . .
}
}
Anti Patterns
try {
doIt();
} catch(Exception e) {
if(e instanceof SomeExceptoin) {
. . .
}
else if(e instanceof OtherExceptoin) {
. . .
}
else if(e instanceof AnotherExceptoin) {
. . .
}
}
// 예외 마다 처리할 방법이 다르다면 편한게 아니다.
GUIDE : 외부와의
interface에서는
RuntimeException도 잡
아라.
예외 클래스 계층
Throwable
Error Exception
RuntimeException
NullPointerException
IllegalArgumentException
일반 예외 클래스
발생했다면 이미 처리할
수 있는 상황이 아니다.
따로 catch하지 않
아도 컴파일 된다.
RuntimeException?
RuntimeException은 따로 catch하지 않아도 컴파일된다.
그래서 별로 관심을 두지 않는다.
그런데 RuntimeException이 발생했다는 것 자체는 버그
가 있다는 것을 의미한다.
예 : NullPointerException. 요놈이 발생했다는 것은 null 체크를 제
대로 하지 않은 경우이다. 버그이다.
버그는 발생할 수도 있다. 잡으면 그만이다. 하지만 로그
가 없으면 잡기 힘들다. 외부 인터페이스에서
RuntimeException을 잡아서 로그에 남기자.
 여기서 말하는 인터페이스는 외부에서 호출하는 경계를 의미한다.
외부 시스템
시스템,
컴퍼넌트,
패키지
GUIDE : 하나의 try 블록
은 적당한 크기를 유지
하라.
try – catch 블럭이 너무 크다면
catch한 예외를 어디서 던졌는지 눈으로 안 보인다.
혹시 2군데에서 같은 예외를 던진 경우 처리 방법이
틀릴 수도 있다.
유지보수 혹은 코드 파악이 어려워 진다.
하나의 try – catch 블록이 30 line을 넘어가지 않게 하
라.
만약 로직상 어쩔 수 없다면? -> 아마도 중첩된 loop가 있는
경우 일 것이다. 예외와 별개로, 새로운 메소드로 뽑는 리팩터
링을 고려해 보라.
Anti Patterns
public void doSomething() throw SomeException {
try {
doIt();
doOther();
doMore();
doAgain();
} catch(SomeException e) {
. . .
} catch(OtherException e) {
. . .
} catch(AnotherException e) {
. . .
} catch(MoreException e) {
. . .
}
}
던질 때의 가이드.
메시지 충실.
잡을 곳을 기준으로 예외 객
체 선택.
메시지를 파싱하게 하지 말
자.
추상예외로 던지지 말자.
GUIDE : 예외를 던질 때
는 반드시 message를
설정한다. 충실하게
메시지를 충실하게.
예외를 왜 던질까?
바라던 행위를 스스로 할 수 없기 때문이다.
밖의 누군가가 처리하라고 던진다.
던진 예외를 잡아서 처리할 수 있을 만
큼 충분한 정보를 제공해야 한다.
정보가 충분하지 않으면 예외를 잡아도 처
리할 수 없다.
메시지를 꼭 왜?
메시지가 자세하지 않아도 처리할 수는 있다.
사용자에게 알려주기.
기본값 사용.
재시도.
그러나 적지 않은 경우 분석할 필요가 있다. 이
때 로그에 가장 좋은 내용은 예외의 메시지 이다
.
정말로 필요가 없을 수도 있다. 그러나 습관을
위해서라도 설정하라. 대부분인 필요한 경우를
위하여
메시지를 사칭한 메시지 예
예외 자체만으로도 다음과 같은 정보를 얻을 수 있다.
Exception 클래스 이름
발생한 클래스 이름과 메소드 이름
호출한 stack
다음과 같이 던져진 예외는 무슨 정보를 제공하나?
runtime이 아닌경우가 있을까? 컴파일 타임을 말하나?
예외라고 말할 것 없다. 이미 예외인 것 안다.
occurred라고? 이미 발생한 것 알고 있다.
더군다나 예외 클래스에서도 정보를 얻지 못한다.
if(…) {
throw new Exception(“runtime exception occurred”);
}
메시지에 따른 유지보수의 차이
메시지가 부실하면
뭐가 안 된다는 보고를 받고
코드 들여다 보면서 상황을 짐작만 하고
그런 짐작을 확인하기 위한 로그 코드를 추가하고
시스템에 배치하고
혹시 짐작이 맞으면 버그 패치하고
시스템에 배치하고 버그 패치가 확인되면 로그 남기는 코딩을 삭제
하여 다시 올리고
짐작 틀리면 계속 반복하고
메시지가 충실하다면. 그리고 로그 남김이 충실하다면
로그 파일로 상황을 파악하고
재현하고
버그 패치하고 시스템에 배치하고
버그 패치만 확인하고.
충실한 메시지
그 예외만으로도 상황을 파악할 수 있게
하는 메시지
시스템을 개선할 수 있을 만큼 충분한
정보를 제공해야 한다.
단지 뭐가 실패했다는 정도로는 부족하
다. 상황이 포함되어야 한다.
Anti Patterns
if(name==null) {
throw new IOException();
}
// IOException 이름 말고는 정보가 없다.
} catch(IOException e) {
throw new OtherException(e);
}
// 상황에 대한 정보가 없다.
} catch(IOException e) {
throw new OtherException(“runtime exception occurred”);
}
// 무의미한 메시지, cause 누락, 그리고 상황에 대한 정보가 없다.
GUIDE : 메시지 템플릿
“some tasking failed.
name=tom, age=10”
메시지 템플릿.
“TASK_NAME failed.” + (name=value)쌍 반복
• TASK_NAME을 결정할 때는 포함된 메소드 이름 활용 강추.
살짝 읽기 쉽게 풀어 주자.
• 만약 메소드 이름이 process13과 같다면 메소드 이름 리팩
토링도 고려해 보자.
• 어차피 TASK_NAME은 stack trace를 통해서 알 수 있지만,
고민하지 말고 메소드 이름을 보고 현재 하던 것을 적어주
자. 습관처럼 작성하자.
• 예 :“config loading failed.”, “authentication failed”,
“message sending failed.”
GUIDE : 외부에서 예외를
catch하여 처리할 상황
을 기준으로 던질 예외
클래스를 선택하라.
그대로 던질까 하나로 던질까
특정 로직을 수행 중에 다양한 예외가
발생할 경우 어떤 예외를 던져야 하나?
외부에서 어떻게 처리할 지가 기준이다.
각 예외 별로 처리방법이 틀릴 경우 각 예외
그대로 던져야 한다.
예외가 뭐였든 간에 처리방법이 동일하다면
하나의 예외로 던지면 된다.
그대로 던질까 하나로 던질까
• 예 : xml config파일을 로딩하는 loadConfig() 메소드
– 다양한 예외(file io, xml parsing, config parsing)가 발생한다.
– 외부에서는 loadConfig()를 호출 시 단지 로딩 성공이냐 혹은
실패냐 만이 관심이다.
– 다양한 예외가 던져진다 하더라도 처리 방법은 동일하다. 로그
를 남기고 시스템을 종료.
• 예 : 레코드 insert 시의 실패
– key가 중복되는 경우의 처리와 DBMS와의 통신 실패 시의 처
리 방법이 다르다.
– 같은 예외로 던진다면 메시지를 파싱해야 한다.
Anti Patterns
try {
doSomething();
} catch(AException e) {
treatIt();
} catch(OtherException e) {
treatIt();
} catch(TheOtherException e) {
treatIt();
} catch(AnotherException e) {
treatIt();
}
// 예외의 종류에 관계없이 처리할 방법이
// 똑같은 경우가 된다면 던지자.
Anti Patterns
try {
doOther();
} catch(SomeException e) {
String message = e.getMessage();
if(message … ) {
treatAsThis();
}
else if(message … ) {
treatAsThat();
}
else if(message … ) {
treatAsIt();
}
}
// 처리할 방법이 다양하다면 복수의 예외를 던져야 한다.
// 그렇지 않을 경우 메시지를 파싱하게 된다.
GUIDE : java.lang의 추상
적인 예외로 던지지 말
자.
추상적인 예외?
Error, Exception, Throwable, RuntimeException과 같
은 추상적인 클래스로 예외를 던지지 말자.
외부 라이브러리를 가져와서 그 모양새를 봤더니.
타 예외의 경우를 먹은 경우다.
상황에 따른 처리를 하려면 별도의 처리가 불가피하다.
예외 클래스는 그 이름만으로도 정보를 제공한다. 그런
데 그 정보제공자체를 포기하는 것이다.
public void someMethod() throws Exception;
Anti Patterns
public void doSomething() throws Exception;
GUIDE : 메시지를 파싱하
게 하지 말자.
메시지 파싱?
메시지는 예외를 처리할 수 있을 만큼 상세하여야 한
다.
그러나 String 메시지를 파싱하여 정보를 추출하게 하
지 말자.
메시지 파싱이 필요한 경우? : 메시지의 내용에 따라
처리할 로직이 달라야 하는 경우
만약 이러한 경우가 발생한다면 예외 클래스에 이러한
정보를 담을 속성을 추가하라. (ex : code)
혹은 별개의 예외로 던져라.
Anti Patterns
if(isRecordExist(record)) {
throw new InsertFailException(“duplicated id”);
}
try {
insertRecored(record);
} catch(SQLException e) {
throw new InsertFailException(“sql failed.”);
}
// 호출하는 쪽에서는 메시지를 파싱해서 처리할 수 밖에 없다.
GUIDE : UI 개발이 아니
라면 message는 오직
디버깅을 위한 것이다.
이에 맞게 message를
작성하라.
디버깅을 위한 메시지?
예외의 메시지는 사용자에게 보여주기에 적당치 않다.
여기서의 사용자는 개발된 시스템을 사용하는 최종 사용자.
메시지의 목적은 시스템 개선이다.
사용자에게 보여주는 내용은 변경되기 쉽고, 다국어도
고려해야 하고, 상황에 종속적일 수 있다.
예외의 메시지를 작성 시에 사용자가 볼지도 모른다는
우려할 필요 없고, 관련된 시간낭비 할 필요 없다.
따라서 굳이 한국어로 할 필요도 없고, 대화체라든가,
하여간에 시간 낭비할 필요 없다.
Anti Patterns
if(someIsFailed) {
String message = null;
if(language.equals(“korean”)) {
message = “소켓 읽기에 실패했습니다.”
}
else if(language.equals(“english”)) {
message = “reading socket failed.”;
}
throw new SomeException(message);
}
// 던지는 예외의 메시지를 UI에서 직접 보여주어서는 않된다.
로그 관련
예외가 처리되었으면 반드시 로
그를 남겨라.
정보를 누락하지 말고 로그로
남겨라.
GUIDE : 예외를 로그로
남길 때 모든 정보를 로
그에 남겨라. stack trace
포함해서.
정보 출력
새로 정의한 예외 클래스이고, 별개의 정보를 가지고
있는 속성이 추가되었다면, 모든 정보를 출력할
getMessage() 메소드를 override하면 편하다.
private String host;
private int port;
@Override
public String getMessage() {
StringBuffer messageSb = new StringBuffer();
messageSb.append(super.getMessage());
messageSb.append(“, host=“).append(host);
messageSb.append(“, port=“).append(port);
return messageSb.toString();
}
stack trace
예외가 발생한 메소드가 호출된 역사.
상황을 파악하는데 아주 중요하다.
사뭇 길어 보이고 로그가 지저분해 보일 수도
있다.
하지만 예외의 목적이 뭐? : 시스템 개선
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
String stackTrace = writer.toString();
GUIDE : 예외의 로그출력
은 정해진 곳에서만 한
다.
로그 출력 위치
예외를 처리한 곳
아무 곳에서나 남기면 로그가 중복된다.
외부와의 인터페이스
이곳에서조차 안 남기면 로그가 남을 지에
대하여 보장하지 못한다.
Anti Patterns
catch(SomeEception e) {
logger.debug(e);
throw new OtherException(“blar.”, e);
}
로그 레벨의 의미
• DEBUG
– 말 그대로 디버깅을 위한 목적이다.
– 아직도 DEBUG로 로그를 출력할 필요가 있다면 아직 안정화가 안된 것이다.
• INFO
– 시스템 동작에 대한 정보를 제공한다.
• WARN
– 현재 운영에는 문제가 없지만, 문제가 될 수 있는 사항
• ERROR
– 시스템 혹은 기타 오류로 운영에 문제가 있는 사항.
– 예외를 잡아서 정상처리한 경우.
• FATAL
– 시스템 운영이 불가능한 경우.
– 예측되지 못한 예외를 잡아서 정상처리 못한 경우.
로그 레벨 선택 방법
버그나 시스템 문제는 아니고, 단지 운영자에게 정보를
제공 INFO
지금은 로그를 남겨두지만, 좀 그렇다 싶으면 DEBUG
디버깅을 위해서 잠시 속살을 보여주는 것이다.
예측되는 예외가 발생하여 알려 주어야 한다 싶으면
WARN
예측되지 않은 예외가 발생하고 정상처리되면 ERROR,
그렇지 않으면 FATAL
로그 레벨의 예
• DEBUG
– 예: 입력받은 값
– 예 : DB에서 읽어온 값.
• INFO
– 예 : 시스템 구동 시간, 읽은 설정파일 위치, 캐싱 리프레쉬 사실.
• WARN
– 예 : 파일 시스템이 10% 남았다.
– 예 : 설정 값을 읽었지만 사용되지 않는다.
• ERROR
– 예 : 설정값이 없어서 default 값을 사용했다.
– 예 : DB 접속이 끊겨서 다시 재접속하였다.
• FATAL
– 설정된 컴퍼넌트를 로딩하지 못했다.
– 예 : DB 접속이 되지 않는다.
다시 강조
예외와 정보를 먹지 말자.
예외 메시지를 충실히.
MORE
예외와 로그도 프로젝트 차원으
로 정책이 마련되어야 한다.
설계 시 입력, 출력과 더불어 예
외도 포함되어야 한다.

More Related Content

What's hot

DDD 구현기초 (거의 Final 버전)
DDD 구현기초 (거의 Final 버전)DDD 구현기초 (거의 Final 버전)
DDD 구현기초 (거의 Final 버전)beom kyun choi
 
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019Kenneth Ceyer
 
Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용흥배 최
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019devCAT Studio, NEXON
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향Young-Ho Cho
 
새해 일어난 일
새해 일어난 일새해 일어난 일
새해 일어난 일Eunhyang Kim
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011Esun Kim
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱PgDay.Seoul
 
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션NHN FORWARD
 
H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호
H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호
H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호KTH, 케이티하이텔
 
Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPSeungmo Koo
 
나의 이직 이야기
나의 이직 이야기나의 이직 이야기
나의 이직 이야기종립 이
 
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정PgDay.Seoul
 
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장Dylan Ko
 
쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기Brian Hong
 
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민XpressEngine
 
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다KWON JUNHYEOK
 
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3Heungsub Lee
 
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기OKKY
 

What's hot (20)

DDD 구현기초 (거의 Final 버전)
DDD 구현기초 (거의 Final 버전)DDD 구현기초 (거의 Final 버전)
DDD 구현기초 (거의 Final 버전)
 
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
 
Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향
 
새해 일어난 일
새해 일어난 일새해 일어난 일
새해 일어난 일
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
 
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
 
H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호
H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호
H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호
 
Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCP
 
나의 이직 이야기
나의 이직 이야기나의 이직 이야기
나의 이직 이야기
 
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
[pgday.Seoul 2022] 서비스개편시 PostgreSQL 도입기 - 진소린 & 김태정
 
Celery
CeleryCelery
Celery
 
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
 
쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기
 
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
 
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
[Devil's camp 2019] 혹시 Elixir 아십니까? 정.말.갓.언.어.입.니.다
 
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
 
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
 

Viewers also liked

알고리즘 문제해결전략 #1
알고리즘 문제해결전략 #1알고리즘 문제해결전략 #1
알고리즘 문제해결전략 #1Byeongsu Kang
 
Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드
Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드
Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드도형 임
 
코딩소림사 Rx java
코딩소림사 Rx java코딩소림사 Rx java
코딩소림사 Rx javaByeongsu Kang
 
멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면Byeongsu Kang
 
Aws summit 2017 사내전파교육
Aws summit 2017 사내전파교육Aws summit 2017 사내전파교육
Aws summit 2017 사내전파교육Byeongsu Kang
 
Kth개발자 세미나 1회
Kth개발자 세미나 1회Kth개발자 세미나 1회
Kth개발자 세미나 1회Byeongsu Kang
 
Scala dreaded underscore
Scala dreaded underscoreScala dreaded underscore
Scala dreaded underscoreRUDDER
 
카카오스토리 웹팀의 코드리뷰 경험
카카오스토리 웹팀의 코드리뷰 경험카카오스토리 웹팀의 코드리뷰 경험
카카오스토리 웹팀의 코드리뷰 경험Ohgyun Ahn
 
Webservice cache strategy
Webservice cache strategyWebservice cache strategy
Webservice cache strategyDaeMyung Kang
 
세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화Jay JH Park
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍Jay JH Park
 
Bitcoin 2.0(blockchain technology 2)
Bitcoin 2.0(blockchain technology 2)Bitcoin 2.0(blockchain technology 2)
Bitcoin 2.0(blockchain technology 2)Wooseung Kim
 
세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발Jay JH Park
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platformJay JH Park
 
세션2. 이더리움 합의 알고리즘과 마이닝
세션2. 이더리움 합의 알고리즘과 마이닝세션2. 이더리움 합의 알고리즘과 마이닝
세션2. 이더리움 합의 알고리즘과 마이닝Jay JH Park
 
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016Taehoon Kim
 
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016Taehoon Kim
 
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016Taehoon Kim
 

Viewers also liked (20)

알고리즘 문제해결전략 #1
알고리즘 문제해결전략 #1알고리즘 문제해결전략 #1
알고리즘 문제해결전략 #1
 
Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드
Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드
Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드
 
코딩소림사 Rx java
코딩소림사 Rx java코딩소림사 Rx java
코딩소림사 Rx java
 
멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면
 
알고리즘2
알고리즘2알고리즘2
알고리즘2
 
Aws summit 2017 사내전파교육
Aws summit 2017 사내전파교육Aws summit 2017 사내전파교육
Aws summit 2017 사내전파교육
 
스프링컨트롤러예외처리,@ExceptionHandler, @ControllerAdvice
스프링컨트롤러예외처리,@ExceptionHandler, @ControllerAdvice스프링컨트롤러예외처리,@ExceptionHandler, @ControllerAdvice
스프링컨트롤러예외처리,@ExceptionHandler, @ControllerAdvice
 
Kth개발자 세미나 1회
Kth개발자 세미나 1회Kth개발자 세미나 1회
Kth개발자 세미나 1회
 
Scala dreaded underscore
Scala dreaded underscoreScala dreaded underscore
Scala dreaded underscore
 
카카오스토리 웹팀의 코드리뷰 경험
카카오스토리 웹팀의 코드리뷰 경험카카오스토리 웹팀의 코드리뷰 경험
카카오스토리 웹팀의 코드리뷰 경험
 
Webservice cache strategy
Webservice cache strategyWebservice cache strategy
Webservice cache strategy
 
세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
 
Bitcoin 2.0(blockchain technology 2)
Bitcoin 2.0(blockchain technology 2)Bitcoin 2.0(blockchain technology 2)
Bitcoin 2.0(blockchain technology 2)
 
세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platform
 
세션2. 이더리움 합의 알고리즘과 마이닝
세션2. 이더리움 합의 알고리즘과 마이닝세션2. 이더리움 합의 알고리즘과 마이닝
세션2. 이더리움 합의 알고리즘과 마이닝
 
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
 
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
 
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
 

Similar to 예외처리가이드

[스프링 스터디 1일차] 예외 처리
[스프링 스터디 1일차] 예외 처리[스프링 스터디 1일차] 예외 처리
[스프링 스터디 1일차] 예외 처리AnselmKim
 
Tcpl 14장 예외처리
Tcpl 14장 예외처리Tcpl 14장 예외처리
Tcpl 14장 예외처리재정 이
 
M3 4 1
M3 4 1M3 4 1
M3 4 1nexthw
 
More effective c++ chapter3 4
More effective c++ chapter3 4More effective c++ chapter3 4
More effective c++ chapter3 4Dong Chan Shin
 
포스트모템디버깅과 프로세스 덤프 실전
포스트모템디버깅과 프로세스 덤프 실전포스트모템디버깅과 프로세스 덤프 실전
포스트모템디버깅과 프로세스 덤프 실전주항 박
 
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들영욱 오
 
김성훈 - 뛰어난 디버거가 되는 방법
김성훈 - 뛰어난 디버거가 되는 방법김성훈 - 뛰어난 디버거가 되는 방법
김성훈 - 뛰어난 디버거가 되는 방법성훈 김
 
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with ExceptionGCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception상현 조
 
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여iamprogrammerofficial
 
[C++ korea] effective modern c++ study item 14 declare functions noexcept if ...
[C++ korea] effective modern c++ study item 14 declare functions noexcept if ...[C++ korea] effective modern c++ study item 14 declare functions noexcept if ...
[C++ korea] effective modern c++ study item 14 declare functions noexcept if ...Seok-joon Yun
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Nam Hyeonuk
 
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기OKKY
 
C# 기초 문법 part 2
C# 기초 문법 part 2C# 기초 문법 part 2
C# 기초 문법 part 2준영 박
 
온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅Ryan Park
 
05. 아키텍트가 알아야할 12 97가지
05. 아키텍트가 알아야할 12 97가지05. 아키텍트가 알아야할 12 97가지
05. 아키텍트가 알아야할 12 97가지YoungSu Son
 
깨끗한 코드 (클린 코드, Clean Code)
깨끗한 코드 (클린 코드, Clean Code)깨끗한 코드 (클린 코드, Clean Code)
깨끗한 코드 (클린 코드, Clean Code)Jay Park
 
Holub on-patterns-2-1
Holub on-patterns-2-1Holub on-patterns-2-1
Holub on-patterns-2-1정환 임
 

Similar to 예외처리가이드 (20)

[스프링 스터디 1일차] 예외 처리
[스프링 스터디 1일차] 예외 처리[스프링 스터디 1일차] 예외 처리
[스프링 스터디 1일차] 예외 처리
 
Tcpl 14장 예외처리
Tcpl 14장 예외처리Tcpl 14장 예외처리
Tcpl 14장 예외처리
 
M3 4 1
M3 4 1M3 4 1
M3 4 1
 
Exception&log
Exception&logException&log
Exception&log
 
More effective c++ chapter3 4
More effective c++ chapter3 4More effective c++ chapter3 4
More effective c++ chapter3 4
 
포스트모템디버깅과 프로세스 덤프 실전
포스트모템디버깅과 프로세스 덤프 실전포스트모템디버깅과 프로세스 덤프 실전
포스트모템디버깅과 프로세스 덤프 실전
 
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
 
김성훈 - 뛰어난 디버거가 되는 방법
김성훈 - 뛰어난 디버거가 되는 방법김성훈 - 뛰어난 디버거가 되는 방법
김성훈 - 뛰어난 디버거가 되는 방법
 
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with ExceptionGCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
 
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
 
[C++ korea] effective modern c++ study item 14 declare functions noexcept if ...
[C++ korea] effective modern c++ study item 14 declare functions noexcept if ...[C++ korea] effective modern c++ study item 14 declare functions noexcept if ...
[C++ korea] effective modern c++ study item 14 declare functions noexcept if ...
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
 
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기
 
C# 기초 문법 part 2
C# 기초 문법 part 2C# 기초 문법 part 2
C# 기초 문법 part 2
 
온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅
 
05. 아키텍트가 알아야할 12 97가지
05. 아키텍트가 알아야할 12 97가지05. 아키텍트가 알아야할 12 97가지
05. 아키텍트가 알아야할 12 97가지
 
깨끗한 코드 (클린 코드, Clean Code)
깨끗한 코드 (클린 코드, Clean Code)깨끗한 코드 (클린 코드, Clean Code)
깨끗한 코드 (클린 코드, Clean Code)
 
20 3 with_statement
20 3 with_statement20 3 with_statement
20 3 with_statement
 
Holub on-patterns-2-1
Holub on-patterns-2-1Holub on-patterns-2-1
Holub on-patterns-2-1
 

More from 도형 임

인공지능과 심리상담
인공지능과 심리상담인공지능과 심리상담
인공지능과 심리상담도형 임
 
Anomaly detection practive_using_deep_learning
Anomaly detection practive_using_deep_learningAnomaly detection practive_using_deep_learning
Anomaly detection practive_using_deep_learning도형 임
 
Deep learning application_to_manufacturing
Deep learning application_to_manufacturingDeep learning application_to_manufacturing
Deep learning application_to_manufacturing도형 임
 
프로그래머를 고려하는 당신에게
프로그래머를 고려하는 당신에게프로그래머를 고려하는 당신에게
프로그래머를 고려하는 당신에게도형 임
 
테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)도형 임
 
코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능도형 임
 
알파고 학습 이해하기
알파고 학습 이해하기알파고 학습 이해하기
알파고 학습 이해하기도형 임
 
Ai 그까이거
Ai 그까이거Ai 그까이거
Ai 그까이거도형 임
 
테스트 케이스와 SW 품질
테스트 케이스와 SW 품질테스트 케이스와 SW 품질
테스트 케이스와 SW 품질도형 임
 
유지보수성이 sw의 품질이다.
유지보수성이 sw의 품질이다.유지보수성이 sw의 품질이다.
유지보수성이 sw의 품질이다.도형 임
 
Release and versioning
Release and versioningRelease and versioning
Release and versioning도형 임
 
고품질 Sw와 개발문화
고품질 Sw와 개발문화고품질 Sw와 개발문화
고품질 Sw와 개발문화도형 임
 
오버라이딩을 사용한 테스트 시의 설정 처리
오버라이딩을 사용한 테스트 시의 설정 처리오버라이딩을 사용한 테스트 시의 설정 처리
오버라이딩을 사용한 테스트 시의 설정 처리도형 임
 
행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스도형 임
 
행복, 그리고 인지과학
행복, 그리고 인지과학행복, 그리고 인지과학
행복, 그리고 인지과학도형 임
 
유지보수를 고려한 SW 개발
유지보수를 고려한 SW 개발유지보수를 고려한 SW 개발
유지보수를 고려한 SW 개발도형 임
 
Git 사용 가이드
Git 사용 가이드Git 사용 가이드
Git 사용 가이드도형 임
 
흰머리 성성하게 개발하기 위해
흰머리 성성하게 개발하기 위해흰머리 성성하게 개발하기 위해
흰머리 성성하게 개발하기 위해도형 임
 
프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법도형 임
 
행복한 소프트웨어 개발
행복한 소프트웨어 개발행복한 소프트웨어 개발
행복한 소프트웨어 개발도형 임
 

More from 도형 임 (20)

인공지능과 심리상담
인공지능과 심리상담인공지능과 심리상담
인공지능과 심리상담
 
Anomaly detection practive_using_deep_learning
Anomaly detection practive_using_deep_learningAnomaly detection practive_using_deep_learning
Anomaly detection practive_using_deep_learning
 
Deep learning application_to_manufacturing
Deep learning application_to_manufacturingDeep learning application_to_manufacturing
Deep learning application_to_manufacturing
 
프로그래머를 고려하는 당신에게
프로그래머를 고려하는 당신에게프로그래머를 고려하는 당신에게
프로그래머를 고려하는 당신에게
 
테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)
 
코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능
 
알파고 학습 이해하기
알파고 학습 이해하기알파고 학습 이해하기
알파고 학습 이해하기
 
Ai 그까이거
Ai 그까이거Ai 그까이거
Ai 그까이거
 
테스트 케이스와 SW 품질
테스트 케이스와 SW 품질테스트 케이스와 SW 품질
테스트 케이스와 SW 품질
 
유지보수성이 sw의 품질이다.
유지보수성이 sw의 품질이다.유지보수성이 sw의 품질이다.
유지보수성이 sw의 품질이다.
 
Release and versioning
Release and versioningRelease and versioning
Release and versioning
 
고품질 Sw와 개발문화
고품질 Sw와 개발문화고품질 Sw와 개발문화
고품질 Sw와 개발문화
 
오버라이딩을 사용한 테스트 시의 설정 처리
오버라이딩을 사용한 테스트 시의 설정 처리오버라이딩을 사용한 테스트 시의 설정 처리
오버라이딩을 사용한 테스트 시의 설정 처리
 
행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스
 
행복, 그리고 인지과학
행복, 그리고 인지과학행복, 그리고 인지과학
행복, 그리고 인지과학
 
유지보수를 고려한 SW 개발
유지보수를 고려한 SW 개발유지보수를 고려한 SW 개발
유지보수를 고려한 SW 개발
 
Git 사용 가이드
Git 사용 가이드Git 사용 가이드
Git 사용 가이드
 
흰머리 성성하게 개발하기 위해
흰머리 성성하게 개발하기 위해흰머리 성성하게 개발하기 위해
흰머리 성성하게 개발하기 위해
 
프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법
 
행복한 소프트웨어 개발
행복한 소프트웨어 개발행복한 소프트웨어 개발
행복한 소프트웨어 개발
 

예외처리가이드

  • 1.
  • 2. About Me 임도형 딴거 재미없어 오직 개발만 하는 삽질 무쟈게 싫어하는. dh-rim@hanmail.net
  • 4. 모든 일에는 예외가 있다. 모든 시스템에는 예측하지 못하는 상황 이 있다. 작업의 절차를 정의하는 프로그래밍에도 예외가 있을 수 밖에 없다.
  • 5. 프로그래밍에서의 예외 입력, 출력 그리고 제 3의 당당한 IO . 예외가 없이는 출력의 특정 값을 사용. if(read()==-1) 정보가 빈약하다. 입력 출력 예외
  • 6. 예외의 종류? 예측 가능한 예외 예측 가능하지 않은 예외
  • 7. 예측 가능한 예외 예측 가능한 만큼 그 처리 자체가 개발 의 일부이다. 그런 상황을 처리하는 것이 당연하다. 로그인이 실패했다. DB에 레코드가 없다. 파일을 찾을 수 없다.
  • 8. 예측 가능하지 않은 예외 버그 아니면 시스템 환경에 기인한다. 실시간 처리는 불가능하다. 대신 개선해 야 한다.
  • 9. 예외 처리가 제대로 되지 않으면? 문제가 발생해도 로그를 보지 않는다. 로그가 중복되거나 누락. 로그에 도움되는 내용이 없다. println(), 혹은 break point에 의지한 디 버깅.
  • 10. 시스템 개선 한번 발생한 예측하지 못하는 상황이 다 시 발생하지 않도록 하는 것. 발생하지 않도록 한다. 발생한다 해도 예측 가능하게 한다. 오로지 로그에 의존한다. 로그는 예외에 의존한다.
  • 11. 잡을 때의 가이드. 먹지 말자. 정보를 누락하지 말자.
  • 12. GUIDE : 예외를 잡았으면 처리하라.
  • 13. 게으르지 말자. 다음과 같은 코드는 절대 있어선 안 된다. 예외 잡아서 걍 콘솔로 출력하면 될 경우는 거의 없다. 컴파일 된다고 코딩이 끝난 게 아니다. 어찌 처리할 지 모른다면 잡지 말자. try { … } catch(SomeException e) { // TODO Auto-generated catch block e.printStackTrace(); }
  • 14. Anti Patterns } catch(SomeException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 잡았으면 무언가 해야 한다.
  • 15. 잡은 후의 유형 처리하고 예외상황 종료 절대적으로 로그를 남겨야 한다. 다시 던진다. 로그를 위해 잡아서 메시지만을 보고 다시 던진다. 메시지를 변경하는 것은 바람직하지 않다. 새 예외로 던진다. 세세한 예외를 더 추상화된 예외로 던질 경우 이 예외를 받은 쪽에서는 cause 예외만으로는 정보가 부족하 다. 추가적인 상황정보 추가는 필수적이다. 무시한다. 뭘 더 해볼 것이 없는 경우. 이 경우 로그조차 필요 없는 경우이다.
  • 16. GUIDE : 예외를 처리했으 면 로그를 남겨라.
  • 17. 로그 유형 로그도 없고 처리도 안 함. -> XXX 최악이다. 차라리 안 잡는 것이 낳다. 뭔가 잘못됐다고 리포팅은 되지만, 재현할 방법이 없다. 처리는 했는데 로그가 없다. -> XX 아주 나쁨 예외가 발생한 상황을 먹어버렸다. 시스템 개선할 여지가 없다.
  • 18. 로그 유형 처리도 하고 로그도 있다. : 다양한 경우가 있다. 한심한 로그(“exception occurred”) -> XX  있으나 마나 한 로그 무심한 로그(“IOException occurred”) -> X  대충 감은 잡힌다. “2번 째 데이터를 못 받았는데, IOException 발생했다면…”  언제까지 감으로 일한 텐가 당연한 로그 -> X 좋은 게 아니다.  예 : “IOException occurred. message=“socket read failed””  메시지 남기는 것은 기본이다. 친절한 로그 -> O 상황을 알려주어야 한다.  예 : “second data reading failed. cause=[IOException, message=“socket read failed.”]”  어떤 상황인지 알려준다. 충분한 로그 -> OK  예 : “second data reading failed. cause=[IOException, message=“socket read failed.”], peer=“10.10.10.13”, port=1234, auth=“base123”, thread=32
  • 19. Anti Patterns } catch(SomeException e) { // do nothing } // 차라리 잡지 말아야 한다. } catch(IOException e) { doOtherInstead(); } // 정상처리가 되었지만, 그 상황에 대한 로그는 없다. } catch(IOException e) { doOtherInstead(); Log.warn(“exception occurred.”); } // 예외가 발생했다는 것 외에는 정보가 없다.
  • 20. Anti Patterns } catch(IOException e) { doOtherInstead(); Log.warn(“IOException occurred.”); } // IOException이란 것만 알지 기타 정보가 없다. } catch(IOException e) { doOtherInstead(); Log.warn(e.toString()); } // 예외 클래스와 예외 메시지는 알지만, 상황을 모른다. // 더욱이 예외의 stack 정보조차 누락되었다.
  • 21. GUIDE : 원 예외의 정보 누락 금지
  • 22. 정보 누락 금지 예외의 목적이 무엇? : 시스템 개선 절대, 잡은 예외의 정보를 누락하지 말자. 반드 시 cause로 설정하라. 많은 것을 요구하는 것이 아니다. 친절한 메시 지까지는 몰라도 최소한 잡은 예외를 누락하지 말자.
  • 23. Anti Patterns catch(SomeEception e) { throw new OtherException(“blar”); } catch(SomeEception e) { throw new OtherException(“blar. e=“+e); }
  • 24. GUIDE : java.lang의 추상 예외로 잡지 말자.
  • 25. 추상 예외로 잡는다면? 코딩하기는 편하다고 착각할 수도 있다. try – catch 블럭에 어떤 코드를 넣어도 컴파일 된다. 이렇게 잡은 예외의 처리 방법이 오직 한가지라고 확신 하지 못한다면(대부분의 그렇다) 언젠가 세세한 예외로 나누게 될 것이다. 편하게 아니다. try { … } catch(Throwable e){ … }
  • 26. Anti Patterns public void doSomething() throw SomeException { try { doIt(); doOther(); doMore(); doAgain(); } catch(Exception e) { . . . } }
  • 27. Anti Patterns try { doIt(); } catch(Exception e) { if(e instanceof SomeExceptoin) { . . . } else if(e instanceof OtherExceptoin) { . . . } else if(e instanceof AnotherExceptoin) { . . . } } // 예외 마다 처리할 방법이 다르다면 편한게 아니다.
  • 29. 예외 클래스 계층 Throwable Error Exception RuntimeException NullPointerException IllegalArgumentException 일반 예외 클래스 발생했다면 이미 처리할 수 있는 상황이 아니다. 따로 catch하지 않 아도 컴파일 된다.
  • 30. RuntimeException? RuntimeException은 따로 catch하지 않아도 컴파일된다. 그래서 별로 관심을 두지 않는다. 그런데 RuntimeException이 발생했다는 것 자체는 버그 가 있다는 것을 의미한다. 예 : NullPointerException. 요놈이 발생했다는 것은 null 체크를 제 대로 하지 않은 경우이다. 버그이다. 버그는 발생할 수도 있다. 잡으면 그만이다. 하지만 로그 가 없으면 잡기 힘들다. 외부 인터페이스에서 RuntimeException을 잡아서 로그에 남기자.  여기서 말하는 인터페이스는 외부에서 호출하는 경계를 의미한다. 외부 시스템 시스템, 컴퍼넌트, 패키지
  • 31. GUIDE : 하나의 try 블록 은 적당한 크기를 유지 하라.
  • 32. try – catch 블럭이 너무 크다면 catch한 예외를 어디서 던졌는지 눈으로 안 보인다. 혹시 2군데에서 같은 예외를 던진 경우 처리 방법이 틀릴 수도 있다. 유지보수 혹은 코드 파악이 어려워 진다. 하나의 try – catch 블록이 30 line을 넘어가지 않게 하 라. 만약 로직상 어쩔 수 없다면? -> 아마도 중첩된 loop가 있는 경우 일 것이다. 예외와 별개로, 새로운 메소드로 뽑는 리팩터 링을 고려해 보라.
  • 33. Anti Patterns public void doSomething() throw SomeException { try { doIt(); doOther(); doMore(); doAgain(); } catch(SomeException e) { . . . } catch(OtherException e) { . . . } catch(AnotherException e) { . . . } catch(MoreException e) { . . . } }
  • 34. 던질 때의 가이드. 메시지 충실. 잡을 곳을 기준으로 예외 객 체 선택. 메시지를 파싱하게 하지 말 자. 추상예외로 던지지 말자.
  • 35. GUIDE : 예외를 던질 때 는 반드시 message를 설정한다. 충실하게
  • 36. 메시지를 충실하게. 예외를 왜 던질까? 바라던 행위를 스스로 할 수 없기 때문이다. 밖의 누군가가 처리하라고 던진다. 던진 예외를 잡아서 처리할 수 있을 만 큼 충분한 정보를 제공해야 한다. 정보가 충분하지 않으면 예외를 잡아도 처 리할 수 없다.
  • 37. 메시지를 꼭 왜? 메시지가 자세하지 않아도 처리할 수는 있다. 사용자에게 알려주기. 기본값 사용. 재시도. 그러나 적지 않은 경우 분석할 필요가 있다. 이 때 로그에 가장 좋은 내용은 예외의 메시지 이다 . 정말로 필요가 없을 수도 있다. 그러나 습관을 위해서라도 설정하라. 대부분인 필요한 경우를 위하여
  • 38. 메시지를 사칭한 메시지 예 예외 자체만으로도 다음과 같은 정보를 얻을 수 있다. Exception 클래스 이름 발생한 클래스 이름과 메소드 이름 호출한 stack 다음과 같이 던져진 예외는 무슨 정보를 제공하나? runtime이 아닌경우가 있을까? 컴파일 타임을 말하나? 예외라고 말할 것 없다. 이미 예외인 것 안다. occurred라고? 이미 발생한 것 알고 있다. 더군다나 예외 클래스에서도 정보를 얻지 못한다. if(…) { throw new Exception(“runtime exception occurred”); }
  • 39. 메시지에 따른 유지보수의 차이 메시지가 부실하면 뭐가 안 된다는 보고를 받고 코드 들여다 보면서 상황을 짐작만 하고 그런 짐작을 확인하기 위한 로그 코드를 추가하고 시스템에 배치하고 혹시 짐작이 맞으면 버그 패치하고 시스템에 배치하고 버그 패치가 확인되면 로그 남기는 코딩을 삭제 하여 다시 올리고 짐작 틀리면 계속 반복하고 메시지가 충실하다면. 그리고 로그 남김이 충실하다면 로그 파일로 상황을 파악하고 재현하고 버그 패치하고 시스템에 배치하고 버그 패치만 확인하고.
  • 40. 충실한 메시지 그 예외만으로도 상황을 파악할 수 있게 하는 메시지 시스템을 개선할 수 있을 만큼 충분한 정보를 제공해야 한다. 단지 뭐가 실패했다는 정도로는 부족하 다. 상황이 포함되어야 한다.
  • 41. Anti Patterns if(name==null) { throw new IOException(); } // IOException 이름 말고는 정보가 없다. } catch(IOException e) { throw new OtherException(e); } // 상황에 대한 정보가 없다. } catch(IOException e) { throw new OtherException(“runtime exception occurred”); } // 무의미한 메시지, cause 누락, 그리고 상황에 대한 정보가 없다.
  • 42. GUIDE : 메시지 템플릿 “some tasking failed. name=tom, age=10”
  • 43. 메시지 템플릿. “TASK_NAME failed.” + (name=value)쌍 반복 • TASK_NAME을 결정할 때는 포함된 메소드 이름 활용 강추. 살짝 읽기 쉽게 풀어 주자. • 만약 메소드 이름이 process13과 같다면 메소드 이름 리팩 토링도 고려해 보자. • 어차피 TASK_NAME은 stack trace를 통해서 알 수 있지만, 고민하지 말고 메소드 이름을 보고 현재 하던 것을 적어주 자. 습관처럼 작성하자. • 예 :“config loading failed.”, “authentication failed”, “message sending failed.”
  • 44. GUIDE : 외부에서 예외를 catch하여 처리할 상황 을 기준으로 던질 예외 클래스를 선택하라.
  • 45. 그대로 던질까 하나로 던질까 특정 로직을 수행 중에 다양한 예외가 발생할 경우 어떤 예외를 던져야 하나? 외부에서 어떻게 처리할 지가 기준이다. 각 예외 별로 처리방법이 틀릴 경우 각 예외 그대로 던져야 한다. 예외가 뭐였든 간에 처리방법이 동일하다면 하나의 예외로 던지면 된다.
  • 46. 그대로 던질까 하나로 던질까 • 예 : xml config파일을 로딩하는 loadConfig() 메소드 – 다양한 예외(file io, xml parsing, config parsing)가 발생한다. – 외부에서는 loadConfig()를 호출 시 단지 로딩 성공이냐 혹은 실패냐 만이 관심이다. – 다양한 예외가 던져진다 하더라도 처리 방법은 동일하다. 로그 를 남기고 시스템을 종료. • 예 : 레코드 insert 시의 실패 – key가 중복되는 경우의 처리와 DBMS와의 통신 실패 시의 처 리 방법이 다르다. – 같은 예외로 던진다면 메시지를 파싱해야 한다.
  • 47. Anti Patterns try { doSomething(); } catch(AException e) { treatIt(); } catch(OtherException e) { treatIt(); } catch(TheOtherException e) { treatIt(); } catch(AnotherException e) { treatIt(); } // 예외의 종류에 관계없이 처리할 방법이 // 똑같은 경우가 된다면 던지자.
  • 48. Anti Patterns try { doOther(); } catch(SomeException e) { String message = e.getMessage(); if(message … ) { treatAsThis(); } else if(message … ) { treatAsThat(); } else if(message … ) { treatAsIt(); } } // 처리할 방법이 다양하다면 복수의 예외를 던져야 한다. // 그렇지 않을 경우 메시지를 파싱하게 된다.
  • 49. GUIDE : java.lang의 추상 적인 예외로 던지지 말 자.
  • 50. 추상적인 예외? Error, Exception, Throwable, RuntimeException과 같 은 추상적인 클래스로 예외를 던지지 말자. 외부 라이브러리를 가져와서 그 모양새를 봤더니. 타 예외의 경우를 먹은 경우다. 상황에 따른 처리를 하려면 별도의 처리가 불가피하다. 예외 클래스는 그 이름만으로도 정보를 제공한다. 그런 데 그 정보제공자체를 포기하는 것이다. public void someMethod() throws Exception;
  • 51. Anti Patterns public void doSomething() throws Exception;
  • 52. GUIDE : 메시지를 파싱하 게 하지 말자.
  • 53. 메시지 파싱? 메시지는 예외를 처리할 수 있을 만큼 상세하여야 한 다. 그러나 String 메시지를 파싱하여 정보를 추출하게 하 지 말자. 메시지 파싱이 필요한 경우? : 메시지의 내용에 따라 처리할 로직이 달라야 하는 경우 만약 이러한 경우가 발생한다면 예외 클래스에 이러한 정보를 담을 속성을 추가하라. (ex : code) 혹은 별개의 예외로 던져라.
  • 54. Anti Patterns if(isRecordExist(record)) { throw new InsertFailException(“duplicated id”); } try { insertRecored(record); } catch(SQLException e) { throw new InsertFailException(“sql failed.”); } // 호출하는 쪽에서는 메시지를 파싱해서 처리할 수 밖에 없다.
  • 55. GUIDE : UI 개발이 아니 라면 message는 오직 디버깅을 위한 것이다. 이에 맞게 message를 작성하라.
  • 56. 디버깅을 위한 메시지? 예외의 메시지는 사용자에게 보여주기에 적당치 않다. 여기서의 사용자는 개발된 시스템을 사용하는 최종 사용자. 메시지의 목적은 시스템 개선이다. 사용자에게 보여주는 내용은 변경되기 쉽고, 다국어도 고려해야 하고, 상황에 종속적일 수 있다. 예외의 메시지를 작성 시에 사용자가 볼지도 모른다는 우려할 필요 없고, 관련된 시간낭비 할 필요 없다. 따라서 굳이 한국어로 할 필요도 없고, 대화체라든가, 하여간에 시간 낭비할 필요 없다.
  • 57. Anti Patterns if(someIsFailed) { String message = null; if(language.equals(“korean”)) { message = “소켓 읽기에 실패했습니다.” } else if(language.equals(“english”)) { message = “reading socket failed.”; } throw new SomeException(message); } // 던지는 예외의 메시지를 UI에서 직접 보여주어서는 않된다.
  • 58. 로그 관련 예외가 처리되었으면 반드시 로 그를 남겨라. 정보를 누락하지 말고 로그로 남겨라.
  • 59. GUIDE : 예외를 로그로 남길 때 모든 정보를 로 그에 남겨라. stack trace 포함해서.
  • 60. 정보 출력 새로 정의한 예외 클래스이고, 별개의 정보를 가지고 있는 속성이 추가되었다면, 모든 정보를 출력할 getMessage() 메소드를 override하면 편하다. private String host; private int port; @Override public String getMessage() { StringBuffer messageSb = new StringBuffer(); messageSb.append(super.getMessage()); messageSb.append(“, host=“).append(host); messageSb.append(“, port=“).append(port); return messageSb.toString(); }
  • 61. stack trace 예외가 발생한 메소드가 호출된 역사. 상황을 파악하는데 아주 중요하다. 사뭇 길어 보이고 로그가 지저분해 보일 수도 있다. 하지만 예외의 목적이 뭐? : 시스템 개선 Writer writer = new StringWriter(); e.printStackTrace(new PrintWriter(writer)); String stackTrace = writer.toString();
  • 62. GUIDE : 예외의 로그출력 은 정해진 곳에서만 한 다.
  • 63. 로그 출력 위치 예외를 처리한 곳 아무 곳에서나 남기면 로그가 중복된다. 외부와의 인터페이스 이곳에서조차 안 남기면 로그가 남을 지에 대하여 보장하지 못한다.
  • 64. Anti Patterns catch(SomeEception e) { logger.debug(e); throw new OtherException(“blar.”, e); }
  • 65. 로그 레벨의 의미 • DEBUG – 말 그대로 디버깅을 위한 목적이다. – 아직도 DEBUG로 로그를 출력할 필요가 있다면 아직 안정화가 안된 것이다. • INFO – 시스템 동작에 대한 정보를 제공한다. • WARN – 현재 운영에는 문제가 없지만, 문제가 될 수 있는 사항 • ERROR – 시스템 혹은 기타 오류로 운영에 문제가 있는 사항. – 예외를 잡아서 정상처리한 경우. • FATAL – 시스템 운영이 불가능한 경우. – 예측되지 못한 예외를 잡아서 정상처리 못한 경우.
  • 66. 로그 레벨 선택 방법 버그나 시스템 문제는 아니고, 단지 운영자에게 정보를 제공 INFO 지금은 로그를 남겨두지만, 좀 그렇다 싶으면 DEBUG 디버깅을 위해서 잠시 속살을 보여주는 것이다. 예측되는 예외가 발생하여 알려 주어야 한다 싶으면 WARN 예측되지 않은 예외가 발생하고 정상처리되면 ERROR, 그렇지 않으면 FATAL
  • 67. 로그 레벨의 예 • DEBUG – 예: 입력받은 값 – 예 : DB에서 읽어온 값. • INFO – 예 : 시스템 구동 시간, 읽은 설정파일 위치, 캐싱 리프레쉬 사실. • WARN – 예 : 파일 시스템이 10% 남았다. – 예 : 설정 값을 읽었지만 사용되지 않는다. • ERROR – 예 : 설정값이 없어서 default 값을 사용했다. – 예 : DB 접속이 끊겨서 다시 재접속하였다. • FATAL – 설정된 컴퍼넌트를 로딩하지 못했다. – 예 : DB 접속이 되지 않는다.
  • 68. 다시 강조 예외와 정보를 먹지 말자. 예외 메시지를 충실히.
  • 69. MORE 예외와 로그도 프로젝트 차원으 로 정책이 마련되어야 한다. 설계 시 입력, 출력과 더불어 예 외도 포함되어야 한다.