I've been looking over, but I don't think it exists.
There is return to essentially force close your function, which is nice, but in my current script, I want if it does something incorrectly, to instead return to the start of the sub function that it exists in.
Are there any functions that exist already to do that, or will I have to make a system in order to let myself do that?
Instead of using return, error out of the function when something is "done incorrectly", then use try/catch in a while-loop:
while 1
try
myFunction();
break; % if myFunction() was successful, this will exit the while loop
catch
% do some sort of processing here, then go back to the while loop
end
end
The catch portion of the try/catch block will execute only if myFunction() had an error. return implies the function succeeded (whether or not it gave correct output is a different issue entirely).
Alternatively, you could put your function in a while-loop as suggested by #natan. Return some sort of error code, then check for that error code in the while condition.
Just use an while 1 loop to wrap around the whole function and continue when you want to restart the function.
Here is how I would do it if you are not looking for error handling, but just outcome handling
finishedSuccesfully = false
while ~finishedSuccesfully
output = myFunction();
finishedSuccesfully = evaluateoutput(output);
end
Related
I'm trying to catch a warning message in a function (testA) embedded with another function (testB) which also contain a warning message. When I try to catch the warning message in testA, ME variable is not generated.
To simplify, I have defined both tests :
Test A
function testA()
warning('testA');
testB();
end
TestB
function testB()
warning('testB');
end
I already tried :
w = warning ('off','all');%%
try
testA()
catch ME
assert(length(ME.message) > 0)
end
w = warning ('on','all');
and also lastwarn
lastwarn('');
% Do your fitting
testA()
% Check which warning occured
[msgstr, msgid] = lastwarn;
switch msgid
case 'testA'
error(msgstr);
end
But I have got the last warning message which is 'testB' in msgstr and I need to get the 'Test A' warning message.
Any idea?
Thank you for your help.
You can't do this well programmatically. Warnings aren't really for control flow.
You can't catch warnings with try/catch. That's only for errors (aka "exceptions").
If this is your code, your best bet is to modify testB so that it returns an additional output argument about the warnings it raised, or the conditions indicated by these warnings. Then have your testA pass those along in some structure in another output argument.
If you're just trying to stop at the warning in the debugger, you could accomplish this by adding identifiers to your warnings, disabling just the one in testA, and then doing a dbstop if warning.
function testA()
warning('myproject:TestA', 'testA');
testB();
end
function testB()
warning('myproject:TestB', 'testB');
end
Then:
warning off myproject:TestA
dbstop if warning
testA
If you really want to programmatically get at the warning, use the same approach of adding identifiers to your warnings, disable just myproject:TestA, and then use lastwarn to grab the warning that does arise.
I am calling an external exec. file (not written by me) using the system() command inside the MATLAB code. For some reasons the external file s/t gives the Segmentation fault error, and if I run the code again, it gets fixed.
Therefore, as we do in other languages, I am using try catch to catch the error, w/o stopping the whole process. Here is what I have written:
flag = false;
while(~flag)
try
system('….');
flag = true;
catch MExc
flag = false;
end
end
However, it does not catch the error. How to fix it?
I doubt that you can catch an exception thrown by an external application when called within Matlab (actually it's not a doubt, I'm certain, but the sentence is much more elegant). Anyway, from my knowledge, an application that shuts down without errors should return an ExitCode equal to 0.
Fortunately, the system function returns that value as its first output argument (official documentation), so try the following code instead:
status = -1;
while (status ~= 0)
[status,cmdout] = system('...');
end
% do something with cmdout
I have some code which I need to run both in MATLAB and in Freemat, using different service functions in each case. To make the whole thing portable I need to find a way to determine which functions to call at the start of my code, depending on which environment I am in.
How does one do that?
I was thinking of using the version command but no too sure if this is really robust.
Use verstring in the context of a try \ catch, the output in matlab will be an error while in Freemat it'll be something like "freemat 4.0", for example:
try
txt=verstring;
output='Freemat';
catch err
output='Matlab';
end
I would try to identify each, and give an error if unsure, or ask the user to identify it manually in such case:
% try to identify if it is freeMat
isDefinatelyFreeMat = false;
try
versionIdentifier=verstring;
if (strcmpi(versionIdentifier(1:7), 'FreeMat'))
isDefinatelyFreeMat = true;
end
catch e
end
% try to identify if it is Matlab
isDefinatelyMatlab = false;
try
versionIdentifier=ver;
if (strcmpi(versionIdentifier.Name, 'Matlab'))
isDefinatelyMatlab = true;
end
catch e
end
% if identification was not successful
if ((isDefinatelyFreeMat && isDefinatelyMatlab) || (~isDefinatelyFreeMat && ~isDefinatelyMatlab))
error('Was unable to identify software.');
% TODO: Ask user to identify software manually
end
I am looking for an elegant way to use a conditional try catch statement.
I suppose it could look something like this:
tryif loose==1
% Do something, like loading the user preferences
catch %Or catchif?
% Hande it
end
So far I know that you can use try catch blocks to let your compiled code run, but force it to stop in a debug session with dbstop if caught error. Now I am basically looking for the opposite:
Normally I want the code to stop if unexpected situations occur (to guarantee the integrity of results) but want to be less strict about certain things sometimes when I am debugging.
How about this:
try
% Do something, like loading the user preferences
catch exception
if loose ~= 1
rethrow(exception)
end
% Handle it
end
I don't know about elegant ;-), but at least it avoids the duplication of "do something".
I know one way to do it, though I would hardly call this elegant:
if loose == 1
try
% Do something, like loading the user preferences
catch
% Hande it
end
else
% Do something, like loading the user preferences
end
The best I've been able to do is:
try
% Do something, like loading the user preferences
catch me
errorLogger(me);
%Handle the error
end
And then
function errorLogger(me)
LOOSE = true;
%LOOSE could also be a function-defined constant, if you want multiple uses.
% (See: http://blogs.mathworks.com/loren/2006/09/13/constants/)
if LOOSE
%Log the error using a logger tool. I use java.util.logging classes,
%but I think there may be better options available.
else
rethrow(me);
end
Then, if desired for production-style deployments, avoid the constant condition checking like this:
function errorLogger(me)
%Error logging disabled for deployment
For the "tryif" functionality, you could assert on the first line of the try block:
try
assert(loose==1)
% Do something
catch err
if strcmp(err.identifier,'MATLAB:assertion:failed'),
else
% Hande error from code following assert
end
end
Note that the "Do something" code will not be executed if loose==1.
For the "catchif" functionality, A.Donda's approach of checking loose~=1 on the first line of the catch block seems quite good.
Is it possible to stop or interrupt a code in MATLAB if a condition is reached and end the simulation of the program code ? eg I have a loop that involves calculating a parameter and the moment the value becomes a complex no. I would like my code to stop executing and return the value of the counter at which the parameter value became complex.
Yes, it is possible. If you want to exit your script, you can use this:
if complex(parameter)
disp(counter);
return;
end
If you want to exit a function and return the value of the counter to the caller, you can use this:
if complex(parameter)
return(counter)
end
If you just want to break out of a loop, use this:
for ...
if complex(parameter)
break;
end
end
print(counter)