例外処理構文
例外処理構文とは、コンピュータプログラミング言語によって提供されるキーワードや構造の集合であり、例外処理を可能にするものです。例外処理とは、プログラムの実行中に発生するエラーの処理を通常の処理から分離することです。例外処理の構文はプログラミング言語によって異なりますが、これは意味的な違いを部分的にカバーするためですが、主に各言語の全体的な構文構造に適合させるためです。一部の言語では、関連する概念を「例外処理」と呼んでいません。また、例外処理を直接的に行う機能を備えていなくても、実装手段を提供している言語もあります。
一般的に、エラー処理ではtry...[catch...][finally...]ブロックが使用され、エラーはthrowステートメントによって作成されますが、命名と構文には大きなばらつきがあります。
例外処理構文のカタログ
Ada
- 例外宣言
Some_Error : 例外;- 例外
Some_Errorを発生させる 「メモリ不足」というメッセージでSome_Error を発生させる-- 特定の診断メッセージ - 例外処理と伝播
Ada.Exceptionsの場合、 Ada . Text_IO ;procedure Foo is Some_Error : exception ; begin Do_Something_Interesting ; exception -- 例外ハンドラーの開始 when Constraint_Error => ... -- 制約エラーを処理します when Storage_Error => -- 有用なメッセージを持つ別の例外として Storage_Error を伝搬します raise Some_Error with "Out of memory" ; when Error : others => -- その他すべてを処理します Ada . Text_IO . Put ( "Exception: " ); Ada . Text_IO . Put_Line ( Ada . Exceptions . Exception_Name ( Error )); Ada . Text_IO . Put_Line ( Ada . Exceptions . Exception_Message ( Error )); end Foo ;アセンブリ言語
ほとんどのアセンブリ言語には、不正なオペコード、プログラムチェック、データエラー、オーバーフロー、ゼロ除算などのイベントを特定のシステムがインターセプトするためのマクロ命令または割り込みアドレスが用意されています。IBMおよびUnivacメインフレームにはSTXITマクロがありました。Digital Equipment Corporationの RT11システムには、プログラムエラー、I/O割り込みなどのためのトラップベクターがありました。DOSには特定の割り込みアドレスがあります。Microsoft Windowsには、プログラムエラーをトラップするための特定のモジュール呼び出しがあります。
ATS
( string , int )の例外MyException (* 例外は値を持つことができます *) main0 ()を実装します: void = try $ raise MyException ( "not enough food" , 2 ) with | ~ MyException ( s , i ) => begin $ extfcall ( void , "fprintf" , stderr_ref , "%s: %d" , s , i ); fileref_close ( stderr_ref ); endBash
#!/usr/bin/env bash #set -e 別のエラーメカニズムを提供しますprint_error (){ echo "エラーが発生しました" } trap print_error exit #list シグナルをtrap tempfile = ` mktemp` trap "rm $tempfile " exit ./other.sh
|| echo warning : other failed echo oops ) echo never printed 次のような構文を使用して、任意のシグナルに応答し、複数のエラーのトラップを設定できます。
trap 'echo Error at line ${LINENO}' ERR
BASIC
BASICではOn Errorのgoto/gosub構造が使用され、現代の例外処理とは大きく異なります。BASICにはグローバルハンドラーが1つしかありませんが、現代の例外処理では例外ハンドラーがスタックされます
ON ERROR GOTOハンドラOPEN "Somefile.txt" FOR INPUT AS # 1 CLOSE # 1 PRINT "ファイルは正常に開かれました" END ハンドラー: PRINT "ファイルが存在しません" END ' 代わりに RESUME を使用して、制御を元の位置に戻すこともできます。 C
C は例外処理を直接サポートしていません。まずエラーを防ぎ、関数からの戻り値をテストするのはプログラマの責任です。
いずれにしても、標準 C で例外処理を実装する方法としては、setjmp() / longjmp()関数を使用する方法があります。
#include <setjmp.h> #include <stdio.h> #include <stdlib.h> 列挙型Exception { NoExceptionThrown = 0 、OutOfBoundsException = 1 、ArithmeticException = 2 、// ... } GLOBAL_EXCEPTION_STATE ; jmp_buf状態; int main ( void ) { // try if ( ! setjmp ( state )) { // 'GLOBAL_EXCEPTION_STATE' を操作するコードif ( GLOBAL_EXCEPTION_STATE != NoExceptionThrown ) { longjmp ( state , 0 ); // 例外キャッチへ移動... } } else { switch ( GLOBAL_EXCEPTION_STATE ) { // catch (OutOfBoundsException) case OutOfBoundsException : printf ( "OutOfBoundsException caught" ); break ; // catch (ArithmeticException) case ArithmeticException : printf ( "ArithmeticException caught" ); break ; // 追加の catch ケース... default : // catch (...) printf ( "Unknown exception caught" ); } } return EXIT_SUCCESS ; } Microsoft固有の
2 つのタイプが存在します。
- 構造化例外処理(SEH)
- ベクトル例外処理 (VEH、Windows XPで導入)
Cプログラミング言語におけるSEHの例:
int filterExpression ( EXCEPTION_POINTERS * ep ) { ep -> ContextRecord -> Eip += 8 ; // 除算命令は2~8バイトでエンコードされる可能性がありますreturn EXCEPTION_CONTINUE_EXECUTION ; } int main ( void ) { static int zero = 0 ; __try { zero = 1 / zero ; asm { nop nop nop nop nop nop nop nop } printf ( "例外を過ぎました。\n " ); } __except ( filterExpression ( GetExceptionInformation ())) { printf ( "ハンドラーが呼び出されました。\n " ); } return 0 ; } C#
ブロックtryには、少なくとも 1 つのcatchorfinally句と、最大で 1 つのfinally句が含まれている必要があります。
System.Webを使用します。 public static void Main () { try { // 例外をスローする可能性のあるコード。} catch ( HttpException ex ) { // HttpException (System.Web.HttpException) を処理します。// 例外オブジェクトは "ex" に格納されます。} catch ( Exception ) { // HttpException 以外の CLR 例外を処理します。// 例外には識別子が割り当てられていないため、参照できません。} catch { // 非 CLR 例外も含め、スローされる可能性のあるすべての例外を処理します。} finally { // 例外がスローされたかどうか、または例外が処理されたかどうかに関係なく、try ブロック (catch 句を含む) を終了するときに常に実行されます。// ファイル ハンドルなどのリソースをクリーンアップして閉じる場合によく使用されます。 // Environment.FailFast() が呼び出されたときやシステム全体のその他の例外条件 (電源喪失など) の場合、または別のスレッドの例外が原因でプロセスがクラッシュした場合は実行されないことがあります。} } C++
import std ; std :: exceptionを使用します。std :: runtime_errorを使用します。 int main () { try { // 何かを行う (例外をスローする可能性があります) mightThrow (); } catch ( const runtime_error e ) { // ランタイムエラー e を処理する} catch ( const exception & e ) { // すべての例外を e としてキャッチする} catch (...) { // 以前に catch ブロックによってキャッチされていない、スローされたすべての型 (例外を拡張しないプリミティブまたはオブジェクトを含む) をキャッチする} } C++では、リソース取得と初期化のテクニックを用いて、例外的な状況でリソースをクリーンアップすることができます。C++は意図的にこれをサポートしていませんfinally。[1]メソッドの外側の中括弧はオプションです。
ColdFusion マークアップ言語 (CFML)
スクリプト構文
< cfscript > try { //throw CF9+ throw ( type = "TypeOfException" , message = "Oops" , detail = "xyz" ); // 代替 throw 構文: throw "Oops" ; // これは上記の例の "message" 値に相当します} catch ( any e ) { writeOutput ( "Error: " & e . message ); rethrow ; //CF9+ } finally { //CF9+ writeOutput ( "エラーがない場合でも実行します" ); } < /cfscript> Adobe ColdFusionドキュメント[2]
タグ構文
<cftry> 例外を引き起こす可能性のあるコード <cfcatch ... > <cftry> 例外処理コードの第1レベル <cfcatch ... > 例外処理コードの第2レベル </cfcatch> < cffinally > 最終コード </ cffinally > </cftry> </cfcatch> </cftry>Adobe ColdFusionドキュメント[3]
Railo-Lucee固有の構文
上記の標準構文に加えて、RailoとLuceeのCFML方言ではステートメントが許可されますretry。[4]
このステートメントは、処理を前のブロックの先頭に戻しますtry。
CFScriptの例:
try { // 例外が発生する可能性のあるコード} catch ( any e ){ retry ; } タグ構文の例:
<cftry><!--- 例外が発生する可能性のあるコード ---><cfcatch> < cfretry > </cfcatch> </cftry>D
import std.stdio ; int main () { try { // 例外をスローする可能性のある処理を実行する} catch ( FileException e ) { // FileException 型の例外を処理する} catch ( Object o ) { // その他の例外を処理するwritefln ( "Unhandled exception: " , o ); return 1 ; } return 0 ; } D では、リソース取得のfinally節または初期化テクニックを使用して、例外的な状況でリソースをクリーンアップできます。
Delphi
- 例外宣言
type ECustom = class ( Exception ) // 例外はExceptionクラスの子です。private FCustomData : SomeType ; // 例外はカスタム拡張を持つことができます。public constructor CreateCustom ( Data : SomeType ) ; // 実装プロパティが必要です。 CustomData : SomeType read FCustomData ; end ; - 例外
raise Exception.Create ( 'Message' ) ; Exceptionを発生させます。CreateFmt ( '値を持つメッセージ: %d, %d' , [ value1 , value2 ]) ; // パラメータについては SysUtils.Format() を参照してください。 ECustom.CreateCustom ( X )を発生させます。 - 例外処理と伝播[5]
try // For finally. try // For except. ... // 例外を発生させる可能性のあるコード。except on C : ECustom do begin ... // ECustom を処理します。... if Predicate ( C. CustomData ) then ... end ; on S : ESomeOtherException do begin // その他の例外として伝搬します。raise EYetAnotherException . Create ( S. Message ) ; end ; on E : Exception do begin ... // その他の例外を処理します。raise ; // 伝搬します。end ; end ; finally // 例外が発生したかどうかに関係なく実行するコード(クリーンアップ コードなど)。end ; Erlang
try % 危険なコードcatch throw :{ someError , X } -> ok ; % 例外を処理error : X -> ok ; % 別の例外を処理_:_ -> ok % すべての例外を処理after % クリーンアップend F#
OCamlベースのに加えてtry...with、F#にはseparate構文があり、これは他の.NET言語の節try...finallyを含むtryブロックと同じ動作をしますfinally
比較のために、これは上記の C# サンプルの翻訳です。
try try () (* 例外をスローする可能性のあるコード。 *) with | :? System . Net . WebException as ex -> () (* WebException を処理します。例外オブジェクトは"ex"に格納されます。 *) | :? exn -> () (* CLR 例外を処理します。例外には識別子が割り当てられていないため、参照できません。 *) | _ -> () (* 非 CLR 例外も含め、スローされる可能性のあるすべてのものを処理します。 *) finally () (* 例外がスローされたかどうか、または例外が処理されたかどうかに関係なく、try ブロックを終了するときに常に実行されます。 多くの場合、ファイル ハンドルなどのリソースをクリーンアップして閉じるために使用されます。Environment.FailFast () が呼び出されたときやシステム全体のその他の例外条件 (電源喪失など) の場合、または別のスレッドの例外が原因でプロセスがクラッシュした場合は実行されないことがあります。 *) 比較のために、以下は OCaml サンプルの翻訳です。
例外MyException of string * int (* 例外は値を持つことができます *) let _ = try raise ( MyException ( "not enough food" , 2 )); printfn "Not reached" with | MyException ( s , i ) -> printf "MyException: %s, %d \n " s i | e -> (* すべての例外をキャッチ *) eprintf "Unexpected exception : %O" e ; eprintf "%O" e . StackTrace Haskell
Haskellには例外のための特別な構文はありません。代わりに、関数によってtry/ catch/ finally/ etc.インターフェースが提供されます。
import Prelude隠蔽( catch ) import Control.ExceptionインスタンスException IntインスタンスException Double main = do catch ( catch ( throw ( 42 :: Int )) ( \ e -> print ( 0 , e :: Double ))) ( \ e -> print ( 1 , e :: Int )) 印刷
(1,42)
このC++と同様に
import std ; int main () { try { throw static_cast < int > ( 42 ); } catch ( double e ) { std :: println ( "(0,{})" , e ); } catch ( int e ) { std :: println ( "(1,{})" , e ); } } 別の例は次のとおりです。
do { -- エラーがスローされる可能性のある文} ` catch ` \ ex -> do { -- 例外が発生した場合に実行される文。'ex' は例外にバインドされています。 } 純粋関数型コードでは、エラー条件が1つだけであれば、型 で十分であり、デフォルトでは Haskell のクラスMaybeのインスタンスになります。より複雑なエラー伝播は、またはモナドを使用することで実現できます。これらのモナドでは、 を使用した同様の機能がサポートされています。Monad ErrorErrorT`catch`
Java
ブロックtryには、少なくとも1つのcatchorfinally節と、最大1つのfinally節が必要です。JavaはExceptions、(キャッチ可能なエラー)とError(通常はより重大で、キャッチ不可能なエラー)を区別します。どちらもThrowable(スローされる可能性のあるオブジェクトの基本クラス)の子孫です。
java.io.IOExceptionをインポートします。 try { // 通常の実行パス。mayThrowIOException (); // IOException をスローできるメソッド} catch ( IOException e ) { // IOException を処理します。// IOException はキャッチする必要があるチェック例外です。} catch ( RuntimeException e ) { // RuntimeException を処理します。// 実行時例外はチェックされず、キャッチが強制されません。} catch ( Exception e ) { // Exception のインスタンスであるものをすべてキャッチします} catch ( Throwable t ) { // Throwable のインスタンスであるものをすべてキャッチします (Exception と Error の両方を含む) } finally { // 例外がスローされたかどうか、または例外が処理されたかどうかに関係なく、try ブロック (finally 句を含む) を終了するときに常に実行されます。// try ブロックで取得したリソースをクリーンアップして閉じます。 // System.exit() が呼び出されたとき、およびその他のシステム全体の例外的な条件 (電源喪失など) では実行されない場合があります。// try-with-resources が言語に追加された後は、ほとんど使用されません (以下を参照)。} 複数のリソースが取得された場合、それらを処理する正しい方法は、ネストされたtryブロックを使用することです。[6]この理由とその他の理由から、try-with-resourcesが言語に追加され、finally節をほぼ完全に置き換えました。tryキーワードの後の括弧で囲まれたリソースは自動的にクリーンアップされます。これらの文で使用されるクラスは、と呼ばれるインターフェースを実装する必要がありますjava.lang.AutoCloseable。[7]これは、 C++などの言語でよく見られる「リソース取得は初期化」というパターンに似ており、リソースはスコープを離れた後にクリーンアップされます。
java.io.BufferedReaderをインポートします。java.io.FileReaderをインポートします。java.io.IOExceptionをインポートします。 try ( FileReader fr = new FileReader ( path ); BufferedReader br = new BufferedReader ( fr )) { // 通常の実行パス。} catch ( IOException e ) { // 例外を処理します。// try ステートメント内のリソースは、その後自動的に閉じられます。} finally { // finally 句を含めることができ、try ステートメント内のリソースが閉じられた後に実行されます。} JavaScript
JavaScriptの設計上、ラウドエラーやハードエラーは極めて稀です。ソフトエラーやクワイエットエラーの方がはるかに多く発生します。ハードエラーは、最も近い文に伝播します。その文には、単一の節、単一の節、またはその両方tryが続く必要があります。catchfinally
try { // 例外がスローされる可能性のあるステートメントthrow new Error ( "error" ); } catch ( error ) { // 例外が発生した場合に実行されるステートメント} finally { // いずれにしてもその後に実行されるステートメント} 文が全くない場合try、Webページはクラッシュしません。代わりに、コンソールにエラーが記録され、スタックがクリアされます。しかし、JavaScriptには、非同期的に外部から呼び出されるエントリポイントという興味深い特徴があります。他のほとんどの言語では、コードの一部が常に実行されているのに対し、JavaScriptは最初から最後まで線形に実行される必要はありません。例えば、イベントリスナー、Promise、タイマーなどは、ブラウザーによって後で呼び出され、コードの他の部分とは独立したコンテキストで共有されながら実行されます。以下のコードでは、4秒ごとに新しいエラーが無期限に、またはブラウザー/タブ/コンピューターが閉じられるまで、どのように発生するかを確認してください。
setInterval ( function () { throw new Error ( "4 秒間隔でスローされるエラーの例。" ); }, 4000 ); もう 1 つの興味深い特徴はポリモーフィズムです。JavaScript はプリミティブ値をエラーとしてスローすることがあります。
try { throw 12345 ; //プリミティブな数値} catch ( error ) { console.log ( error ); // 12345をプリミティブな数値としてコンソールに出力します} このcatch句はあらゆる種類のエラーを捕捉する包括的なエラー処理であることに注意してください。何年も前に実装された実験的なGecko拡張機能や現在は削除されている拡張機能を除けば、エラーの種類ごとに異なるハンドラーを割り当てる構文上の手段はありません。代わりに、文throwの中に文を挿入するcatchか、複数の条件分岐を使用してエラーを伝播させる方法があります。Javaの例と、それとほぼ同等のJavaScriptの例を比較してみましょう。
// Java の例try { Integer i = null ; i.intValue (); // NullPointerException をスローします} catch ( NullPointerException error ) { //変数は null の可能性があります} catch ( ArithmeticException error ) { // 数値に関する問題を処理し} // JavaScript での近似 #1 try { // 例外がスローされる可能性のあるステートメントvar example = null ; example . toString (); } catch ( error ) { if ( error . type === "TypeError" ) { // 変数が null になる可能性がある} else if ( error . type === "RangeError" ) { // 数値に関する問題を処理する} } // JavaScript での近似 #2 try { try { //例外がスローされる可能性のあるステートメントvar example = null ; example.toString (); } catch ( error ) { if ( error.type !== "TypeError" ) throw error ; // 変数は null の可能性があります} } catch ( error ) { if ( error.type ! == "RangeError" ) throw error ; //数値に関する問題の処理} 例外のもう一つの側面は、例外を非同期的に処理するPromiseです。例外を非同期的に処理することで、エラーハンドラ内のエラーが外部に伝播しないという利点があります。
new Promise ( function () { throw new Error ( "例のエラーです!" ); }). catch ( function ( err ) { console . log ( "キャッチされました " , err ); }); また、イベント ハンドラーが Promise にどのように結び付けられるかについても確認します。
addEventListener ( "unhandledrejection" , function ( event ) { console . log ( event . reason ); event . preventDefault (); // console.error 経由でコンソールにエラーが記録されないようにします (デフォルトの動作) }); new Promise ( function () { throw new Error ( "例のエラーです!" ); }); 最後に、JavaScript はマーク アンド スイープ ガベージ コレクションを使用するため、循環参照があってもブラウザーが自動的に無効なオブジェクトを消去するため、throw ステートメントによるメモリ リークが発生することはありません。
try { // 例外がスローされる可能性のあるステートメントconst obj = {}; obj . selfPropExample = obj ; // 循環参照throw obj ; } catch ( error ) { // 例外が発生した場合に実行されるステートメント} Kotlin
try { // 例外をスローする可能性のあるコード} catch ( e : SomeException ) { // 例外を処理するコード} Lisp
Common Lisp
(エラーを無視( / 1 0 )) ( handler-case ( progn ( print "式を入力してください" ) ( eval ( read ))) ( error ( e ) ( print e ))) ( unwind-protect ( progn ( print "式を入力してください" ) ( eval ( read ))) ( print "この print は、finally と同様に常に実行されます。" )) Lua
Luaは関数pcallとxpcall関数を使用し、関数をブロックxpcallとして受け取りますcatch
- 定義済み関数
関数foo ( x ) if x then return x else error "真の値ではありません" end end 関数の試行( arg )成功、値= pcall ( foo 、arg ) 成功しなかった場合はprint ( "エラー: " .. tostring ( value ))し、そうでない場合はprint ( "戻り値: " .. tostring ( value ))を出力します。 試行( "hello" ) -- 返される値: hello 試行( nil ) -- エラー: stdin:5: 真の値ではありません 試行({}) -- 返される値: テーブル: 00809308 if foo ( 42 ) then print "Success" end -- 成功 - 無名関数
if pcall ( function () -- エラーが発生する可能性のある処理を実行します。end ) then print "No errors" -- 保護された呼び出しが成功した場合に実行されます。else print "Error occurred" -- 保護された呼び出しが失敗した場合に実行されます。end print "Done" -- 常に実行されます 次世代シェル
- カスタム例外タイプの定義
MyError (エラー)と入力します。- 例外
MyErrorをスローする(「これが起こった」)- 例外処理と伝播
try { # 何か} catch ( e : MyError ) { guard e . val = 7 # ... } catch ( e : MyError ) { # ... } catch ( e : Error ) { # ... }- 例外を無視する - catchなしのtry
try 1 / 0 # null と評価される- 例外を無視する - "tor"演算子
"tor" は try-or 演算子です。左辺の引数の評価中に例外が発生した場合、右辺の引数が評価されます。
1 / 0 tor 20 # は20と評価されます- 「ブロック」 - 例外を使用して値を返す機能
my_result = block my_block { # "block" は下記の return によってスローされた例外をキャッチします # 計算を実行します if calculation_finished () { my_block . return ( 42 ) # 例外をスローします } }Objective-C
- 例外宣言
NSException *例外= [ NSException exceptionWithName : @"myException"理由: @"yourReason"ユーザー情報: nil ]; - 例外
@throw exception ; - 例外処理と伝播
@try { ... } @catch ( SomeException * se ) { // 特定の例外タイプを処理します。... } @catch ( NSException * ne ) { // 一般的な例外を処理します。... // 例外を伝播して、より高いレベルで処理されるようにします。@throw ; } @catch ( id ue ) { // スローされたすべてのオブジェクトをキャッチします。... } @finally { // 例外が発生したかどうかに関係なく、クリーンアップを実行します。... } OCaml
例外 MyException of string * int (* 例外は値を持つことができます *) let _ = try raise ( MyException ( "not enough food" , 2 )); print_endline "Not reached" with | MyException ( s , i ) -> Printf . printf "MyException: %s, %d \n " s i | e -> (* すべての例外をキャッチ *) Printf . eprintf "Unexpected exception : %s" ( Printexc . to_string e ); (* Ocaml >= 3.11 を使用している場合は、バックトレースを印刷することもできます: *) Printexc . print_backtrace stderr ; (* 事前に Printexc.record_backtrace を true に設定するか、環境変数 OCAMLRUNPARAM="b1" を設定して、バックトレースの記録を有効にする必要があります *)Perl 5
Perlの例外処理メカニズムは、ブロックdie内をラップする場合に例外をスローするために使用します。 の後の特殊変数には、から渡された値が含まれますeval { ... };eval$@die
Perl 5.005では、文字列だけでなくオブジェクトもスローする機能が追加されました。これにより、例外の種類をより適切にイントロスペクションし、処理することが可能になります。
eval { open ( FILE , $file ) || die MyException::File -> new ( $! ); while ( <FILE> ) { process_line ( $_ ); } close ( FILE ) || die MyException::File -> new ( $! ); }; if ( $@ ) { # 例外オブジェクトは $@ にありますif ( $@ -> isa ( 'MyException::File' )) { # ファイル例外を処理します} else { # 一般的な例外処理# または 'die $@' で再スローします} } 擬似__DIE__シグナルは、 の呼び出しを処理するためにトラップできますdie。これはグローバルであるため、例外処理には適していません。ただし、サードパーティ製パッケージからの文字列ベースの例外をオブジェクトに変換するには使用できます。
local $SIG { __DIE__ } = sub { my $err = shift ; if ( $err -> isa ( 'MyException' )) { die $err ; # 再スロー} else { # それ以外の場合は、 $err を文字列として MyException を構築しますdie MyException::Default -> new ( $err ); } }; 上記の形式は、$@例外がスローされてから文中でチェックされるまでの間にグローバル変数が変更されると、失敗することがあります。これはマルチスレッド環境だけでなく、シングルスレッド環境であっても、他のコード(通常はオブジェクトの破棄時に呼び出される)がチェックコードよりも先にグローバル変数をリセットした場合に発生する可能性があります。以下の例は、この問題を回避する方法を示しています([1]または[2]を参照 。[3]も参照)。ただし、戻り値を使用できなくなるというデメリットがあります。if ($@)
eval { # 例外をスローする可能性のあるコード(「die」を使用)ですが、return文は使用していません。1 ; }またはdo { #ここで例外を処理します。例外文字列は$@に格納されています。 }; Comprehensive Perl Archive Network ( CPAN ) のいくつかのモジュールは、基本的なメカニズムを拡張します。
Error例外クラスのセットを提供し、try/throw/catch/finally 構文の使用を可能にします。TryCatch、およびすべてでは、定型句の代わりに try/catch/finally 構文を使用して例外を正しく処理できます。Try::TinyNice::TryException::Classは、派生例外クラスの基底クラスおよびクラスメーカーです。およびで完全な構造化スタックトレースを提供します。$@->trace$@->trace->as_stringFatalopen、、、など、true/false を返す以前に定義された関数をオーバーロードします。closeこれにより、組み込み関数などを、例外をスローしたかのように使用できるようになります。readwrite
PHP
// 例外処理は PHP バージョン 5 以上でのみ使用できます。try { // 例外をスローする可能性のあるコード throw new Exception ( 'Invalid URL.' ); } catch ( FirstExceptionClass $exception ) { // この例外を処理するコード} catch ( SecondExceptionClass $exception ) { // 別の例外を処理するコード} finally { // 例外が発生したかどうかに関係なく、クリーンアップを実行します。}PowerBuilder
例外処理はPowerBuilderバージョン8.0以降 で利用できます
試す // 通常の実行パスCATCH (ExampleException ee) // ExampleExceptionを処理する最後に // このオプションセクションは、上記のtryまたはcatchブロックのいずれかの終了時に実行されます終了試行
PowerShell
バージョン1.0
trap [例外] { # 例外発生時に実行される文} # 例外がスローされる可能性のある文バージョン2.0
Try { Import-Module ActiveDirectory } Catch [Exception1] { # 例外が発生した場合に実行されるステートメント (例外に一致) } Catch [Exception2],[Exception3etc] { # 例外が発生した場合に実行されるステートメント (いずれかの例外に一致) } Catch { # 例外が発生した場合に実行されるステートメント (より具体的には処理されない ) }Python
f = None try : f = open ( "aFileName" , "w" ) f . write ( could_make_error ()) except IOError : print ( "ファイルを開けません" ) except : # すべての例外をキャッチ print ( "予期しないエラーが発生しました" ) else : # 例外が発生しなかった場合に実行 print ( "ファイルの書き込みが正常に完了しました" ) finally : # クリーンアップアクション、常に実行 if f : f . close ()R
tryCatch ({ stop ( "ここでエラーが通知されます" ) # デフォルトの S3 クラスは simpleError で、error のサブクラスです。cat ( "この行と次の行は、エラーが前にトラップされているため実行されません\n" ) stop ( structure ( simpleError ( "mySpecialError メッセージ" ), class = c ( "specialError" , "error" , "condition" )) ) } , specialError = function ( e ){ cat ( "specialError クラスのエラーをキャッチします\n" ) } , error = function ( e ){ cat ( "デフォルトのエラーをキャッチします\n" ) } , Finally = { cat ( "クリーンアップを実行します (例: setwd)\n" ) } ) レボル
REBOL [ タイトル: 「例外とエラー処理の例」]; ブロックを試してください; エラーをキャプチャします! そしてオブジェクトに変換します!エラーの場合? 例外: try [ 1 / 0 ][プローブ解除例外] ; ATTEMPTはブロックの値、またはエラーの場合はnoneを返します。print attempt [ divide 1 0 ]; ユーザーが生成した例外はどんなデータ型でも構いません!例: func [ "例外をスローする関数" ][ throw "私は文字列です!例外" ] catch [例]; ユーザーが生成した例外にも名前を付けることができ、関数には追加の実行時属性を含めることができます。洗練された: func [ "名前付きエラー例外をスローする関数" [ catch ] ][ throw /name make error! "エラーです!例外" 'moniker ] catch /name [洗練された] 'monikerレックス
signal on halt ; do a = 1 say a do 100000 /* a delay */ end end halt : say "プログラムはユーザーによって停止されました" exit Ruby
begin # 気の利いたことをするraise SomeError , "これはエラーメッセージです!" # やられた! rescue SomeError # これは SomeError 例外が発生したときに実行されるrescue AnotherError => error # ここで、例外オブジェクトは# `error' 変数から参照されるrescue # これは StandardError から派生したすべての例外をキャッチするretry # これは begin セクションを再度実行するelse # これは例外が発生しなかった場合にのみ実行されるensure # これは例外の有無にかかわらず常に実行されるend S-Lang
お試しください { % 例外をスローする可能性のあるコード } SomeErrorをキャッチ: { % この例外を処理するコード } SomeOtherErrorをキャッチ: { % この例外を処理するコード } 最後に % オプションブロック { % このコードは常に実行されます }関数を使用して新しい例外を作成することができますnew_exception。例:
new_exception ("MyIOError", IOError, "私のI/Oエラー");MyIOErrorは、 のサブクラスとして と呼ばれる例外を作成します。例外は、任意のS-LangIOErrorオブジェクトをスローできる throw ステートメントを使用して生成できます。
Smalltalk
[ 「例外をスローする可能性のあるコード」] on : ExceptionClass do: [ : ex | 「例外を処理するコード」 ]一般的なメカニズムはメッセージによって提供されます。[8]例外は のサブクラスである通常のオブジェクトであり、インスタンスを作成してそれにメッセージ(例: )を送信することで例外をスローします。処理メカニズム()もまた、 によって実装された通常のメッセージです。スローされた例外は処理ブロッククロージャにパラメータとして渡され、クエリを実行したり、場合によっては に送信して実行フローを続行したりできます。on:do:Error#signalMyException new signal#on:do:BlockClosure#resume
Swift
例外処理はSwift 2以降でサポートされています
enum MyException : ErrorType { case Foo ( String , Int ) } func someFunc ( ) throws { throw MyException.Foo ( "食料が足りません" , 2 ) } do { try someFunc () print ( "到達していません" ) } catch MyException.Foo ( let s , let i ) { print ( " MyException: \( s ) , \( i ) " ) } catch { print ( "予期しない例外: \( error ) " ) } Tcl
if { [ catch { foo } err ] } { "エラー: $err"を出力します} Tcl 8.6 以降では、try コマンドもあります。
try { someCommandWithExceptions } on ok { res opt } { # 通常のケースを処理します。} trap ListPattern1 { err opt } { # ListPattern1 に一致するエラーコードを持つ例外を処理します。 } trap ListPattern2 { err opt } { # ... } on error { err opt } { # その他すべてを処理します。} finally { # try ブロックの後に実行する必要があるコマンドを実行します。} VBScript
With New Try : On Error Resume Next '何かする(1つのステートメントのみを推奨). Catch : On Error GoTo 0 : Select Case . Number Case 0 'この行は、VBScriptのCaseステートメントに「Is」キーワードがないため、'Case Else'句を使用する場合に必要です。'例外なしCase SOME_ERRORNUMBER '例外処理Case Else '不明な例外End Select : End With ' *** クラスを試す ***クラスを試すPrivate mstrDescription Private mlngHelpContext Private mstrHelpFile Private mlngNumber Private mstrSource Public Sub Catch ( ) mstrDescription = Err.Description mlngHelpContext = Err.HelpContext mstrHelpFile = Err.HelpFile mlngNumber = Err.Number mstrSource = Err.Source End Sub パブリックプロパティGet Source () Source = mstrSource EndプロパティパブリックプロパティGet Number () Number = mlngNumber Endプロパティ パブリックプロパティGet HelpFile () HelpFile = mstrHelpFile EndプロパティパブリックプロパティGet HelpContext () HelpContext = mlngHelpContext EndプロパティパブリックプロパティGet Description () Description = mstrDescription EndプロパティEndクラス [9]
Visual Basic 6
例外処理の構文はBasicと非常に似ています。エラー処理は各プロシージャごとにローカルに行われます。
On Error GoTo HandlerLabel 'エラーが発生すると、FunctionまたはSub関数内で定義されているHandlerLabelにジャンプします。 'またはOn Error GoTo 0 'エラー処理をオフにします。エラーが発生すると致命的なランタイムエラーが発生し、アプリケーションが停止します。 'またはOn Error Resume Next 'オブジェクトErrが設定されていますが、次のコマンドで実行は継続されます。Errオブジェクトを使用してエラー状態を確認できます。'... Err . Raise 6 '組み込みオブジェクトErrを使用して「オーバーフロー」エラーを生成します。エラーハンドラーがない場合、呼び出しプロシージャは同じ構文で例外をキャッチできます。 '... FinallyLabel : 'プロシージャ内の共通ラベル(他の言語の Finally セクションの非公式エミュレーション)'クリーンアップコード、常に実行されるExit Sub 'プロシージャを終了 'Exit Sub文の後なので、次のコードはエラーが発生しない場合の実行では非表示です。HandlerLabel : '共通ラベルを定義します。ここでは例外処理に使用されます。If Err . Number = 6 Then '通常はSelect Case文の方が適しています。Resume FinallyLabel '特定のラベルで実行を続行します。通常は他の言語で「Finally」の意味を持つラベルです。'またはResume Next '「Err.Raise 6」の次の文で実行を続行します。 'またはResume '「Err.Raise 6」の(繰り返し)文で実行を続行します。End If MsgBox Err.Number & " " & Err.Source & " " & Erl & " " & Err.Description & " " & Err.LastDllError '重要なエラープロパティを含むメッセージボックスを表示します。'ErlはVB6組み込みの行番号グローバル変数です(使用されている場合)。通常は、コンパイル前に各コード行に番号ラベルを付けるIDEアドインが使用されます。Resume FinallyLabel 「Try」クラスのオブジェクトを使用する例外処理の具体的な(非公式の)実装の例。
With New Try : On Error Resume Next 'クラス「Try」の新しいオブジェクトを作成し、それを使用します。そして、このオブジェクトをデフォルトとして設定します。「Dim T As New Try: ... ... T.Catch '何かを実行します(1つのステートメントのみを推奨)。Catch : On Error GoTo 0 : Select Case . Number 'Try.Catch() プロシージャを呼び出します。そして、エラー処理をオフにします。そして、Try.Number プロパティの結果(組み込み Err オブジェクトの Err.Number プロパティの値)に対して、"switch のような" ステートメントを使用します。Case SOME_ERRORNUMBER '例外処理Case Is <> 0 'Err.Number がゼロの場合、エラーは発生していません。'不明な例外End Select : End With ' *** クラスを試す *** Private mstrDescription As String Private mlngHelpContext As Long Private mstrHelpFile As String Private mlngLastDllError As Long Private mlngNumber As Long Private mstrSource As String Public Sub Catch ( ) mstrDescription = Err.Description mlngHelpContext = Err.HelpContext mstrHelpFile = Err.HelpFile mlngLastDllError = Err.LastDllError mlngNumber = Err.Number mstrSource = Err.Source End Sub パブリックプロパティGet Source () As String Source = mstrSource Endプロパティ パブリックプロパティGet Number () As Long Number = mlngNumber Endプロパティ パブリックプロパティGet LastDllError () As Long LastDllError = mlngLastDllError Endプロパティ パブリックプロパティGet HelpFile () As String HelpFile = mstrHelpFile Endプロパティ パブリックプロパティGet HelpContext () As Long HelpContext = mlngHelpContext Endプロパティ パブリックプロパティGet Description () As String Description = mstrDescription End Property [9]
Visual Basic .NET
ブロックTryには、少なくとも 1 つの節CatchまたはFinally句と、最大で 1 つのFinally節が含まれている必要があります。
Try ' ここで実行するコードCatch ex As Exception When condition ' 特定の条件が満たされた場合に例外を処理します。例外オブジェクトは "ex" に格納されます。Catch ex As ExceptionType ' 指定されたタイプの例外を処理します (例: DivideByZeroException、OverflowException など) Catch ex As Exception ' 例外を処理します (以前に指定されていないタイプのすべての例外をキャッチします) Catch ' スローされる可能性のあるすべての例外を処理します (非 CLR 例外を含む)。Finally ' 例外がスローされたかどうか、または処理されたかどうかに関係なく、try ブロック (catch 句を含む) を終了するときに常に実行されます。'ファイル ハンドルなどのリソースをクリーンアップして閉じる場合によく使用されます。' Environment.FailFast() が呼び出された場合や、その他のシステム全体の例外条件 (電源喪失など)、または別のスレッドの例外によってプロセスがクラッシュした場合は実行されない場合があります。End Try ビジュアルプロローグ
try % 保護するブロックcatch TraceId do % 例外発生時に実行するコード。TraceIdは例外情報へのアクセスを提供します。finally % 他の部分の動作に関係なく、コードが実行されます。end try [ 10]
X++
public static void Main ( Args_args ) { try { //例外をスローする可能性のあるコード。} catch ( Exception :: Error ) // またはその他の例外タイプ。{ // エラーを処理します。} catch { // 以前に処理されていないその他の例外タイプを処理します。} // ここのコードは、例外がキャッチされる限り実行されます。}参考文献
- ^ ビャーネ・ストロウストルップのFAQ
- ^ 「例外処理」。2014年1月2日時点のオリジナルよりアーカイブ。2014年1月1日閲覧
- ^ “例外処理タグ”. 2014年1月2日時点のオリジナルよりアーカイブ。2014年1月1日閲覧。
- ^ https://issues.jboss.org/browse/RAILO-2176 # JBossコミュニティの問題追跡チケットを追加
retry - ^ Borland、Delphi バージョン 7.0、オンラインヘルプ
- ^ ブロッホ、ジョシュア (2018).『Effective Java』第3版. アディソン・ウェスレー. 商品9, 54ページ. ISBN 978-0-13-468599-1
- ^ 「try-with-resources文(Java™チュートリアル > 必須Javaクラス > 例外)」
- ^ “Pharo by Example”. 2009年10月21日時点のオリジナルよりアーカイブ。2010年3月20日閲覧。
- ^ ab “Try-Catch for VB”. 2016年4月16日時点のオリジナルよりアーカイブ。2012年3月17日閲覧。
- ^ http://wiki.visual-prolog.com/index.php?title=Language_Reference/Terms#Try-catch-finally