[erlang] 예외

2015. 12. 23. 02:44프로그래밍/ETC

728x90
728x90

분산 어플리케이션 제작이 목표라면 오류 처리의 작동 방식이 매우 중요하다.


소스

https://github.com/ElementalKiss/Erlang/blob/master/example/try_test.erl


erlang에서 예외를 잡는 방법

예외를 발생시킬 것 같은 함수를 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


스택 추적으로 현재 함수가 반활될 때 반활할 스택에 있는 함수들의 목록을 보여준다.


728x90
반응형

'프로그래밍 > 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