例外への応答
概要
MATLAB® ソフトウェアの既定の設定では、例外がスローされると現在実行中のプログラムを停止します。ただし、プログラムで例外をキャッチすると、誤りに関する情報を収集し、適切な方法で特定の状況に対処できます。このためには、try/catch
ステートメントが必要です。
try/catch ステートメント
期待どおりの結果が生じない可能性のあるコードがステートメントに含まれる場合は、これらのステートメントを try/catch
ブロックに入れます。エラーが発生した場合はキャッチされ、適切に処理されます。
try/catch
ステートメントは、次の疑似コードにようになり、次の 2 つの部分で構成されます。
try
とcatch
ステートメント間のすべての行を含む、try
ブロック。catch
とend
ステートメント間のすべての行を含む、catch
ブロック。
try Perform one ... or more operations A catch ME Examine error info in exception object ME Attempt to figure out what went wrong Either attempt to recover, or clean up and abort end B Program continues
このプログラムは、try
ブロックのステートメントを実行します。エラーが見つかると、try
ブロックの残りのステートメントをスキップし、catch
ブロックの始め (上の A
の位置) にジャンプします。try
ブロックのすべての演算が成功すると、catch
ブロックが完全にスキップされ、end
ステートメントに続く最初の行 (点 B
) に進みます。
try
、catch
、end
コマンドと、try
と catch
ブロックのコードは、別の行に指定することを推奨します。同じ行にこれらのコンポーネントのいずれかを組み合わせる場合は、以下のようにコンマで区切ります。
try, surf, catch ME, ME.stack, end
ans =
file: 'matlabroot\toolbox\matlab\graph3d\surf.m'
name: 'surf'
line: 49
メモ
try
または catch
ブロック内では、入れ子関数を定義することはできません。
Try ブロック
実行時に、コードは try
ブロックに入り、通常のプログラムの一部と同様に各ステートメントが実行されます。エラーが見つからなかった場合、MATLAB では catch
ブロックが完全にスキップされ、end
ステートメントに従って実行を続けます。try
ステートメントのいずれかにエラーがあると、MATLAB はそのブロックの残りのステートメントは実行せずに、すぐに try
ブロックを終了し、catch
ブロックに入ります。
Catch ブロック
catch
コマンドは、catch
ブロックの開始をマークし、例外の原因についての情報を含むデータ構造へのアクセスを提供します。これは、以前の疑似コードの変数 ME
として表示されます。ME
は MException
オブジェクトです。例外が発生すると、MATLAB は MException
オブジェクトを作成し、そのエラーを処理する catch
ステートメントに含めてオブジェクトを返します。
catch
ステートメントでは引数を指定する必要はありません。MException
オブジェクトで提供される情報やメソッドが必要でない場合は、catch
キーワードのみを指定します。
MException
オブジェクトは、エラーのあるプログラムの内部コードによって作成されます。このオブジェクトは、エラーに関する情報を含むプロパティをもちます。この情報は、何が起こったかを特定したり、対処方法を決定する際に役立ちます。MException
オブジェクトではメソッドへのアクセスも提供され、例外に応答できるようになります。
catch
ブロックに入ると、MATLAB ではステートメントが順番に実行されます。これらのステートメントでは、以下を試みることができます。
エラーの解決
エラーに関する詳細情報の収集
MException
オブジェクトの情報に基づいた、適切な応答エラーの発生したコードの残した環境のクリーンアップ
catch
ブロックは、多くの場合、rethrow
コマンドで終わります。rethrow
では、例外が初めにスローされたときの状態に呼び出しスタックの情報を保ち、MATLAB で現在の関数を終了させます。この関数が最上位にある場合、つまり、他の関数によって呼び出されなかった場合は、プログラムが終了します。エラーの発生した関数が別の関数で呼び出された場合は、呼び出し側の関数に戻ります。プログラムは実行を続け、上位レベルの関数に戻ります。ただし、呼び出しのいずれかが上位レベルの try
ブロック内で行われた場合は例外で、この場合は対応する catch ブロックが実行されます。
例外の処理方法についての提案
以下の例では、イメージ ファイルの内容を読み込みます。これには詳細なエラー処理が含まれており、エラーに対して実行できる提案アクションの一部について説明します。
イメージを読み取る関数がエラーをスローおよびキャッチする方法にはいくつかあります。
最初の
if
ステートメントは、関数が入力引数を指定して呼び出されているかどうかをチェックします。入力引数が指定されていない場合、プログラムはエラーをスローし、エラーを修正するための入力引数を提案します。try
ブロックでは、ファイルを開いて読み取りが試行されます。ファイルを開けなかった場合や、読み込みに失敗した場合は、プログラムで結果の例外がキャッチされ、MException
オブジェクトが変数ME1
に保存されます。catch
ブロックでは、指定されたファイルが見つからなかったかどうかのチェックが行われます。見つからなかった場合は、ファイル名拡張子の一般的なバリエーション (たとえば、jpg
の代わりにjpeg
) を使用して、操作が再試行されます。これは、元のtry/catch
に入れ子にされたtry/catch
ステートメントを使用して行われます。
function d_in = read_image(filename) % Check the number of input arguments. if nargin < 1 me = MException('MATLAB:notEnoughInputs','Not enough input arguments.'); aac = matlab.lang.correction.AppendArgumentsCorrection('"image.png"'); me = me.addCorrection(aac); throw(me); end % Attempt to read file and catch an exception if it arises. try fid = fopen(filename,'r'); d_in = fread(fid); catch ME1 % Get last segment of the error identifier. idSegLast = regexp(ME1.identifier,'(?<=:)\w+$','match'); % Did the read fail because the file could not be found? if strcmp(idSegLast,'InvalidFid') && ... ~exist(filename,'file') % Yes. Try modifying the filename extension. switch ext case '.jpg' % Change jpg to jpeg filename = strrep(filename,'.jpg','.jpeg'); case '.jpeg' % Change jpeg to jpg filename = strrep(filename,'.jpeg','.jpg'); case '.tif' % Change tif to tiff filename = strrep(filename,'.tif','.tiff'); case '.tiff' % Change tiff to tif filename = strrep(filename,'.tiff','.tif'); otherwise fprintf('File %s not found\n',filename); rethrow(ME1); end % Try again, with modified filenames. try fid = fopen(filename,'r'); d_in = fread(fid); catch ME2 fprintf('Unable to access file %s\n',filename); ME2 = addCause(ME2,ME1); rethrow(ME2) end end end
この例では、次のような、例外への応答で実行できる操作をいくつか説明します。
MException
オブジェクトのidentifier
フィールドを、エラーの考えられる原因と比較。この場合、関数は識別子がファイルが見つからなかったこととを示す'InvalidFid'
で終了しているかどうかをチェックします。入れ子になっている
try/catch
ステートメントを使用して、改善された入力で操作を再試行。この場合、関数はファイル名拡張子の既知のさまざまなバリエーションを使用して、開く操作と読み取る操作を再試行します。適切なメッセージを表示。
最初の
MException
オブジェクトを 2 番目のcause
フィールドに追加推奨される修正を
MException
オブジェクトに追加。例外を再スロー。これによりプログラムの実行が停止し、エラー メッセージが表示されます。
エラーによって引き起こされた望ましくない結果もクリーンアップすることをお勧めします。たとえば、エラーの発生後に開いたままになっている図を閉じます。