问题
I've been browsing Matlab's exception handling pages, and having a bit of difficulty finding a complete minimum working example of an exception being handled by a function in the call stack that is above where the exception is generated. Would anyone be able to point to such a page, or confirm that it is lacking?
Thanks.
回答1:
I had in mind something like the following minimum working example, showing the mechanics in handing an error from an invoked function to a caller. TMW agrees that something like this would fill in a gap in their documentation (they assisted in creating this example).
% 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
The output:
----------------
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's Capture Information About Exceptions page shows how, at each level (i.e., each try/catch block), one can create a new exception and append exceptions from lower level functions (instead of just propagating those exceptions upward).
One of the things I found from this experiment was that the exception objects don't automatically get cascaded into a chain of exception objects at each level. This has to be done manually.
Another little detail is that, even though MException
can manufacture an exception, it differs from an actual error (or an error created with error
) in that it still needs to be thrown explicitly. In contrast, throwing is done automatically by real errors and errors created using error
.
来源:https://stackoverflow.com/questions/51272681/matlab-minimum-working-example-of-handling-exception-higher-up-in-call-stack