例外への応答
概要
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オブジェクトに追加。例外を再スロー。これによりプログラムの実行が停止し、エラー メッセージが表示されます。
エラーによって引き起こされた望ましくない結果もクリーンアップすることをお勧めします。たとえば、エラーの発生後に開いたままになっている図を閉じます。