6.11. kink/EXCEPTION¶
6.11.1. exception型¶
exceptionは、プログラムの実行時エラーを表現する、 (Message, Traces, 省略可能なNext) の不変なタプルである。
Message
Messageは、エラーメッセージのstr値である。
Traces
Tracesは、trace値の有限長の列である。traceはスタックの根からトップに向けて並ぶ。
省略可能なNext
exceptionは、Next属性として、他のexception値を持つか持たないかのどちらかである。
exception Eからはじまり、Nextをたどって得られるexception値の列は、例外のチェーンと呼ばれる。ここでEは、チェーンのメインの例外であると呼ばれる。例外のチェーンは常に有限長である。
例外のチェーンは、報告するべき例外が複数あるときに構築される。たとえば、CONTROL.with_finallyは、$bodyが例外を投げて、cleanupサンクも例外を投げたときに、チェーンされた例外を投げる。
例外はデバッグのためのもの
例外は実行時エラーのデバッグのための情報だけを含む。プログラム的なエラー処理のための、階層的なカテゴリーやエラーコードを含むことはない。
呼び出し元に、プログラム的な情報を渡す必要がある場合は、継続渡しスタイルの採用を検討しよう。呼び出しスタックの深いところから、処理を中断する必要がある場合は、継続渡しスタイルとCONTROL.with_returnを混ぜることを検討しよう。
6.11.1.1. Exception.message¶
messageは、Message属性と等しいstr値を戻す。
6.11.1.2. Exception.traces¶
tracesは、Traces属性のtrace値を持つvecを戻す。
6.11.1.3. Exception.have_next?¶
have_next?は、ExceptionがNext属性を持つかどうかを戻す。
6.11.1.4. Exception.next¶
nextは、Next属性のexceptionを戻す。
事前条件
Exception.have_next? == true
6.11.1.5. Exception + Tail¶
+ 演算子、つまりop_addメソッドは、Exceptionの例外チェーンとTailの例外チェーンを連結した、新しいチェーンのexceptionを戻す。
事前条件
Tailはexceptionでなければならない。
6.11.1.6. Exception.raise¶
raiseはExceptionを投げる。
raiseの末尾では、次の抽象命令列が評価される:
(val Exception)
(raise)
6.11.1.7. Exception.desc_iter¶
desc_iterは、Exceptionを説明するstr値のiterを戻す。
iterの要素は、Printer.print_lineメソッドで印字されることが期待される。
:CONTROL.require_from('kink/')
CONTROL.try(
{ 10 // 0 }
{ _not_reach_here_ }
{(:Exc)
Exc.desc_iter.each{(:Str)
stderr.print_line(' ' + Str)
}
}
)
# Output:
# -- main exception
# [..root..]
# ,,,
# [builtin:kink-mods/kink/CONTROL.kn L101 C10 body] :R = -->body
# {(stdin) L4 C8 op_intdiv} { 10 -->// 0 }
# Num.op_intdiv(Divisor): zero division: 10 is divided by 0
6.11.1.8. E1 == E2¶
== 演算子、つまりop_eqメソッドは、ふたつの例外が等しい属性を持つかどうかを戻す。
事前条件
E2はexceptionでなければならない。
6.11.2. EXCEPTION.new(Message ...[Traces=TRACE.current_traces])¶
newは、MessageをMessage属性として、TracesをTraces属性として、Next属性なしで、新しいexceptionを作って戻す。
事前条件
Messageはstrでなければならない。
Tracesはtrace値のvecでなければならない。
6.11.3. EXCEPTION.is?(Val)¶
is?は、Valがexceptionであるかどうかを戻す。