我一直在浏览Matlab的异常处理页面,在查找异常的完整最小工作示例方面有些困难,该示例由异常生成上方的调用堆栈中的函数处理。任何人都可以指向这样的页面,或确认缺少该页面吗?
谢谢。
答案 0 :(得分:0)
我想到了下面的最小工作示例,该示例显示了将错误从已调用函数传递给调用方的机制。 TMW同意,这样的事情会填补他们文档中的空白(他们帮助创建了这个示例)。
% main.m
%-------
fprintf(1,'----------------\nRunning foo(1,2)\n')
try
foo(1,2)
catch ME0
ME0
end
fprintf(1,'\n');
fprintf(1,'----------------\nRunning foo(1,[2 3])\n')
try
foo(1,[2 3])
catch ME0
ME0
end
fprintf(1,'----------------\nRunning foo(0,4)\n')
try
foo(0,4)
catch ME0
ME0
end
% foo.m
%------
function foo(A,B)
try
barDbar(A,B)
catch ME1
fprintf(1,'\n');
fprintf(1,'Running catch block in %s\n',mfilename)
ME1, drawnow('update') % Doesn't always flush stdout !!
% No `throw` command, error doesn't propagate to main as ME0
end
end
% barDbar.m
%----------
function barDbar(A,B)
try
foobar(A,B);
catch ME2
fprintf(1,'\n');
fprintf(1,'Running catch block in %s\n',mfilename)
ME2, drawnow('update') % Doesn't always flush stdout !!
throw(ME2) % Required to "escalate" error to caller
end
end
% foobar.m
%---------
function V = foobar(V1,V2)
V = cat(1,V1,V2);
fprintf(1,'\n');
% The following only executes if `cat` does *not* encounter
% an error
fprintf(1,'%s encountered no error.\n',mfilename)
if V1 == 0
fprintf(1,'Creating artificial exception instead.\n')
ME = MException( 'foobar:ArtificalException' , ...
'foobar added artifical exception' );
ME, drawnow('update') % Doesn't always flush stdout !!
throw( ME )
end % if
end
输出:
----------------
Running foo(1,2)
foobar encountered no error.
----------------
Running foo(1,[2 3])
Running catch block in barDbar
ME2 =
MException with properties:
identifier: 'MATLAB:catenate:dimensionMismatch'
message: 'Dimensions of matrices being concatenated are not consistent.'
cause: {0x1 cell}
stack: [4x1 struct]
Running catch block in foo
ME1 =
MException with properties:
identifier: 'MATLAB:catenate:dimensionMismatch'
message: 'Dimensions of matrices being concatenated are not consistent.'
cause: {0x1 cell}
stack: [3x1 struct]
----------------
Running foo(0,4)
foobar encountered no error.
Creating artificial exception instead.
ME =
MException with properties:
identifier: 'foobar:ArtificalException'
message: 'foobar added artifical exception'
cause: {}
stack: [0x1 struct]
Running catch block in barDbar
ME2 =
MException with properties:
identifier: 'foobar:ArtificalException'
message: 'foobar added artifical exception'
cause: {}
stack: [4x1 struct]
Running catch block in foo
ME1 =
MException with properties:
identifier: 'foobar:ArtificalException'
message: 'foobar added artifical exception'
cause: {}
stack: [3x1 struct]
TMW的Capture Information About Exceptions page显示了如何在每个级别(即每个try / catch块)创建一个新的异常并从较低级别的函数附加异常(而不仅仅是向上传播这些异常)。
我从该实验中发现的一件事是,异常对象不会自动在每个级别上级联成一系列的异常对象。这必须手动完成。
另一个小细节是,尽管MException
可以产生异常,但它与实际错误(或使用error
创建的错误)不同,因为它仍然需要显式抛出。相反,实际错误和使用error
创建的错误会自动引发。