Create MException object with a custom non-empty stack (without actually throwing it)
5 ビュー (過去 30 日間)
古いコメントを表示
Dear Matlab Community,
Is it possible to create a valid MException object with a non-empty stack without actually throwing it?
The goal is to execute something somewhere in the code hierarchy and collect the occuring errors with a purpose to process them later in the top-level GUI code, e.g.
function errs = myMethod( this, args )
errs = MException.empty();
% ... do some safe stuff ...
try % ... do some unsafe stuff ...
catch err, errs = [ errs; err ];
% ... do some cleanup ...
return;
end
% ... do more safe stuff ...
try % ... do more unsafe stuff ...
catch err, errs = [ errs; err ];
% ... do some cleanup ...
return;
end
% continue
end
In the example above, the ERR output value will be either an empty array of MExceptions (i.e. no errors), or a scalar MException including the complete stack of the error location, or a vector of such. The actual code may have more hierarchy levels, i.e.
function errs = myMethod( this, args )
someErrs = this.doSomeStuff( someArgs );
moreErrs = this.doMoreStuff( moreArgs );
restErrs = this.doRestStuff( restArgs );
errs = [ someErrs; moreErrs; restErrs ];
end
... where each called submethod or function has similar ERRS output, which are collected to a single vector in the top-level code.
My question is, whether this is possible to locally create a custom MException with a complete local or custom stack without actually throwing it, e.g.:
% ... do some safe stuff ...
if ( someErrorCondition )
% do specific cleanup
% create an exception, but don't throw it, just collect
err = MException( 'myFunc:myErr', 'my error message', dbstack() );
errs = [ errs; err ];
end
% ... do more safe stuff ...
Unfortunately, the syntax above will not work (third "stack" argument is not supported), the stack field of MException is only set by throwing it, and is read-only for an existing MException.
The only way to create an MException object with a custom non-empty stack is seemingly to actually manually throw an exception using error( errStruct ) syntax:
% ... do some safe stuff ...
if ( someErrorCondition )
% do specific cleanup
% create an error specification structure with a custom stack
err = struct( 'identifier', 'myFunc:myErrr', 'message', 'my error message', 'stack', dbstack() );
% throw an exception and catch it immediately,
% then it will have a non-empty user-defined stack
try error( err ); catch err; end
% collect an exception
errs = [ errs; err ];
end
% ... do more safe stuff ...
The latter way works, but seems to be rather ugly and possibly includes a significant overhead to throw-and-catch an error, especially if this happens multiple times for multiple errors.
A possible solution would be to collect the errors as a cell array instead of an array of MExceptions. This would allow using some alternative error format, but would also require a dedicated error-format-dependent error processing code at the top-level, and this is what I would prefer to avoid as long as there's a way to use the native MExceptions.
So,
– is there a way to create an MException object with a custom stack, or
– is there some typical alternative approach for such multiple error handling?
Thanks in advance!
0 件のコメント
回答 (1 件)
Steven Lord
2022 年 4 月 21 日
Preallocate a cell array.
M = cell(1, 3);
Run the code that may throw an error. If it does, catch the error in the appropriate element of the cell array. I'll do this three times, where the first and third do error and the second does not.
try
x = [1 2] + [1 2 3]; % Error, can't add a 1-by-2 and a 1-by-3
catch ME
M{1} = ME;
end
try
q = 1:10; % Does not error
catch ME
M{2} = ME;
end
try
y = [1 2; 3 4]*magic(3); % Error, can't multiply a 2-by-2 and a 3-by-3
catch ME
M{3} = ME;
end
Let's look at the cell array. The first and third cells are non-empty, the second is empty.
celldisp(M)
When we concatenate the three cells together using a comma-separated list the empty cell basically disappears, leaving us our two errors.
theErrors = [M{:}]
The first is M{1} and the second is M{3}.
isequal(theErrors(1), M{1})
isequal(theErrors(2), M{3})
Is theErrors the MException array that you were hoping to create?
参考
カテゴリ
Help Center および File Exchange で Error Handling についてさらに検索
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!