- add a "verbose" control (instead of polluting the user's command window willy-nilly) and to return any status messages.
- create one error message with all relevant text in it (because this could be caught and handled trivially).
Try/Catch Evalc and display output if error
15 次查看(过去 30 天)
显示 更早的评论
Hi everyone,
I have a tricky question :) I use evalc to call a function (which is not mine and which I don't to modify). But sometimes this function throws an error.
My problem is that the error message sent by this function is not explicit at all and all the details are in some text output before the error. And since I am in evalc I don't see these outputs. Is there a way of displaying that ?
small exemple :
- the function that I can not to modify
function blackbox()
disp('explicit explanation');
error('see above');
end
- my function
function my_code()
try
T = evalc('blackbox()');
catch
error(['oops: ' T]);
end
end
What I want is for my_code() to display 'explicit explanation'. But of course if I do what I wrote above, the T is undefined (because evalc/blackbox throwed an exception)
thanks for your help !
update: maybe it was not clear enough: but what I want is to get all the messages that were supposed to be displayed by the function that returned the error ... and I can't find that in the ME .... In the example above, I want to be able to display 'explicit explanation'
1 个评论
Stephen23
2017-7-3
编辑:Stephen23
2017-7-3
This is basically a search for hack to "fix" bad code design: using disp as the main way of communicating with the user. The best solution would be to rewrite that function:
If the person writing that function had done these things then your task would be trivial to solve: to catch the error message is all that would be required. After all, that is exactly what error messages are intended for, and have supporting commands and methods for! Instead, because someone used the wrong tool for the job, you are suffering trying to solve an unsolvable problem.
Bad design can never be properly fixed using hacks, and ultimately just causes more problems and fragility than it is worth. I know that this is not the answer you are looking for, but the best answer is write that function properly to put all text into the error message.
采纳的回答
Billy St. John
2020-5-5
Inefficencies and bad designs aside, for anyone who needs to solve the original problem, try the following:
% General Approach
exception = [];
output = evalc('try, someFunc(); catch E, exception = E; end');
% ... perform processing on 'output' and 'exception' (if not empty)
% Original Example Implementation
function blackbox()
disp('explicit explanation');
error('see above');
end
function my_code()
blackBoxException = [];
T = evalc('try, blackbox(); catch E, blackBoxException = E; end');
disp(T);
if ~isempty(blackBoxException)
disp(getReport(blackBoxException));
end
% Note: I'd recomend reformatting the getReport() output and either rethrowing it or displaying
% it as a warning. A few strsplit's and/or regexprep's can help with formatting.
The above would display the following:
>> my_code();
explicit explanation
Error using my_code>blackbox (line #)
see above
Error in my_code (line #)
T = evalc('try, blackbox(); catch E, blackBoxException = E; end');
>>
更多回答(3 个)
Jan
2017-7-3
编辑:Jan
2017-7-3
Why do you need evalc? If the output is written to the command window, you get the information directly without tricks.
try
T = blackbox();
catch ME
error('oops: %s', ME.message);
end
If you want to grab the output to the command line, you can do this with another tool also, e.g. FEX: CmdWinTool:
fprintf('### Start\n');
try
T = blackbox();
catch ME
error('oops: %s', ME.message);
end
Str = CmdWinTool('getText');
Msg = strsplit(Str, '\n');
Ini = find(strcmp(Msg, '### Start'), 1, 'last');
Msg = Msg(Ini + 1:length(Msg));
I use evalc for a code, which spends 25% of the runtime with output to the command window. The output to the screen is useful for a single run of the program, but if it is called with 1000 cases for a self-test, nobody could read this pile of text. Therefore suppressing the output let the code run much faster, but in case of errors, the specific call is restarted without evalc:
try
S = evalc('process(myData)');
catch ME
fprintf(2, '%s\n', ME.message);
fprintf(2, 'Run again with screen output:\n');
process(myData);
end
2 个评论
Jan
2017-7-3
@Pierre: If you cann write "T=blackbox()", use "blackbox()" without "T=". You have two conflicting needs: 1. the function should not output anything, 2. you want to catch the output in case of an error. One of them must be preferred to the other.
I would not consider these 7 lines for warpping the call and hiding the output in case of a successful run as "third party".
Fangjun Jiang
2017-6-30
Try this:
function my_code()
try
T = evalc('blackbox()');
catch ME
display(ME.message);
end
end
Image Analyst
2017-6-30
If you use
try
catch ME
end
You can get a lot of information from ME.
Wrap the contents of all your functions in a try/catch block:
% Sample usage
try
% Some code that might throw an error......
catch ME
callStackString = GetCallStack(ME);
errorMessage = sprintf('Error in program %s.\nTraceback (most recent at top):\n%s\nError Message:\n%s', ...
mfilename, callStackString, ME.message);
WarnUser(errorMessage);
end
The function GetCallStack() is attached below.
5 个评论
Image Analyst
2017-7-3
Stephen, thanks for clarifying. After experimenting around it looks like if you use evalc(), it will step into the blackbox function but the disp() function does not print to the command window. I even changed it to fprintf and that didn't either. I didn't expect that. You'd think that since it executes disp, it would spew output to the command window.
Getting rid of evalc() makes it not even step into the blackbox function at all, which I didn't expect. It seems to recognize, before even executing blackbox, that there is an output being requested when none are capable of being returned and it throws the error in the main program before even going into blackbox and the disp function inside.
Indeed curious behavior but as Stephen said, better program design will cure all that.
Stephen23
2017-7-3
编辑:Stephen23
2017-7-3
" You'd think that since it executes disp, it would spew output to the command window."
Surely the whole point of evalc is that it does NOT display anything in the command window? The evalc help states: "anything that would normally be written to the command window, except for error messages, is captured and returned in the character array T".
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!