2015. 12. 23. 02:44ㆍ프로그래밍/ETC
분산 어플리케이션 제작이 목표라면 오류 처리의 작동 방식이 매우 중요하다.
소스
https://github.com/ElementalKiss/Erlang/blob/master/example/try_test.erlerlang에서 예외를 잡는 방법
예외를 발생시킬 것 같은 함수를 try-catch로 감싸는 것.
함수 호출을 catch식으로 감싸는 것.
예외 발생시키기
exit(Why) - 프로세스 종료.(예외를 잡지 않을 경우 연결된 모든 프로세스에 broadcast)
throw(Why) - 함수가 예외를 던질 수 있다. 선택1. 통상적인 경우만 처리하고 예외 무시, 선택2. try-catch로 감싸서 오류 처리.
erlang:error(Why) - crashing error를 표시. 호출자가 예기치 못한 상황 발생.
try-catch
표현 식
1 2 3 4 5 6 7 8 9 10 11 | try FuncOrExpressionSequence of Pattern1 [when Guard1] -> Expressions1; Pattern2 [when Guard2] -> Expressions2; ... catch ExceptionType: ExPattern1 [when ExGuard1] -> ExExpressions1; ExceptionType: Expattern2 [when ExGuard2] -> ExExpressions2; ... after AfterExpressions end | cs |
순서
FuncOrExpressionsSequence 평가 -> 이상 없음 -> Pattern1 등의 매치 발생.
FuncOrExpressionsSequence 평가 -> 예외 발생 -> ExceptionType 애텀에 따라 ExPattern1 등과 매칭
ExceptionType는 예외가 어떻게 생성되었는지 말해주는 애텀.
throw, exit, error 중 하나다.
after은 FuncOrExpressionSequence를 처리한 이후에 정리에 사용된다.
try 또는 catch 영역에 있는 Expressions 코드가 실행 된 후 즉시 실행된다. 하지만 AfterExpressions의 반환 값은 유실된다.
예외처리 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | -module(try_test). -export([gen_excpt/1, demo/0]). gen_excpt(1) -> a; gen_excpt(2) -> throw(a); gen_excpt(3) -> exit(a); gen_excpt(4) -> {'EXIT', a}; gen_excpt(5) -> erlang:error(a). demo() -> [catcher(I) || I <- [1,2,3,4,5]]. catcher(N) -> try gen_excpt(N) of Val -> {N, normal, Val} catch throw:X -> {N, caught, thrown, X}; exit:X -> {N, caught, exited, X}; error:X -> {N, caught, error, X} end. % result % 8> c(try_test). % {ok,try_test} % 9> try_test:demo(). % [{1,normal,a}, % {2,caught,thrown,a} % {3,caught,exited,a} % {4,normal,{'EXIT',a} % {5,caught,error,a}] | cs |
이렇게 사용 하는 것이 erlang 프로그래밍 관용법이라고 한다.
어떤 함수가 일으킬 수 있는 모든 유형의 예외를 우리가 잡고 식별할 수 있음을 보여준다.
Catch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | demo2() -> [{I, (catch gen_excpt(I))} || I <- [1,2,3,4,5]]. % result2 % 4> c(try_test). % {ok,try_test} % 5> try_test:demo2(). % [{1,a}, % {2,a}, % {3,{'EXIT',a}}, % {4,{'EXIT',a}}, % {5, % {'EXIT',{a,[{try_test,gen_excpt,1, % [{file,"try_test.erl"},{line,8}]}, % {try_test,'-demo2/0-lc$^0/1-0-',1, % [{file,"try_test.erl"},{line,31}]}, % {try_test,'-demo2/0-lc$^0/1-0-',1, % [{file,"try_test.erl"},{line,31}]}, % {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,673}]}, % {shell,exprs,7,[{file,"shell.erl"},{line,686}]}, % {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]}, % {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]}}}] | cs |
가능한 모든 예외 잡기
_:_ - 모든 예외를 처리하는 코드
_ - 기본 태그인 throw를 가정하기 때문에 모든 오류를 잡아낼 수는 없다.
구식 방식
case(catch... ) of... X
try ... of ... O
스택 추적
erlang:get_stacktrace()를 호출하여 스택을 추적할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | demo3() -> try gen_excpt(5) catch error:X -> {X, erlang:get_stacktrace()} end. % 7> c(try_test). % {ok,try_test} % 8> try_test:demo3(). % {a,[{try_test,gen_excpt,1,[{file,"try_test.erl"},{line,8}]}, % {try_test,demo3,0,[{file,"try_test.erl"},{line,54}]}, % {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,673}]}, % {shell,exprs,7,[{file,"shell.erl"},{line,686}]}, % {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]}, % {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]} % 9> | cs |
스택 추적으로 현재 함수가 반활될 때 반활할 스택에 있는 함수들의 목록을 보여준다.
'프로그래밍 > ETC' 카테고리의 다른 글
[erlang, notepad++] erlang 플러그인 설치 (2) | 2016.01.03 |
---|---|
[디버깅] 조건 디버깅(VS2015) (3) | 2016.01.02 |
[디버깅] 메모리 디버깅(VS2015) (0) | 2016.01.02 |
[erlang] 순차 프로그래밍 (0) | 2015.12.16 |
MySql 연결하기 (2) | 2015.08.27 |
딱딱한 페이지 그만(작성중) (2) | 2015.08.24 |
슈퍼 글로벌 변수 (1) | 2015.08.07 |