I'm trying to implement a bug reporting system in my code so I put a try/catch around the function that is run to start the program. It's a programmatic GUI so most of the subfunctions are callbacks for buttons or other GUI elements. However whenever an error is thrown in these subfunctions, it is not caught. Some of the subfunctions are defined in other files as they are other programmatic GUI files.
My question is, is there anyway to catch errors that are more than one function level deep?
Example below:
I run CeleST to start the program
function CeleST
try
% Global try-catch
CSTMainWindow()
catch exception
generateReport(exception) % bugReporter
end
CSTMainWindow is a programattic GUI file and here is one of the pushbuttons:
uicontrol('parent',mainPanel,'style','pushbutton','string','1. Process videos...','position',[500 yFilters+hFilters+10 170 60],'callback',#processVideo);
However errors in processVideo are not caught
processVideo:
function processVideo(hObject,eventdata) %#ok<INUSD>
set(mainFigure,'Visible','off');
CSTProcessVideos % Programmatic GUI File for another window
set(mainFigure,'Visible','on');
flagConsistentButton = false;
checkSequences
populateFilters
end
Even putting undefined variables in the subfunctions throws errors but they're not caught by my try/catch. Any suggestions or am I doing something wrong? Do I really have to put try-catch blocks around everything?
GTSMainWindow is not calling processVideo. Instead the function is used as a callback and called later.
Basically every callback function must care for it's own errors, put the try catch into the processVideo function and it will catch the error.
Related
I am running a script which calls a function, and if a certain condition is met, inside the function, I want the whole thing just to terminate (and by that I do not mean I want to close matlab using exit). Is that possible? I know I can use return or break to return to the script, however I want the script to stop as well if this condition is met.
The only function I know of that does this is error. This throws an exception, and, if no exception handlers with try and catch are installed in the calling script, will terminate and return to command prompt. Which is what you want, as far as I understand. It prints an error message though. This could be suppressed if you guard all code in the top-level script with a try catch handler. However this will have to be specific to the one error and it makes debugging ("stop-on-error") much more difficult.
The thing is that the only use case I see for this behavior (termination of whole program on certain event) is when a non recoverable error occurs, and in that case printing an error message is indeed appropriate.
In case the script is successful termination of the whole program is not really the right way. All functions should return to give the upper layers of the code to perform some clean-up action, like saving the output data or so.
I am building a GUI in MATLAB (2016a) which I will be compiling and deploying. I want to try to do some global error handling, and it occurs to me that any command given to the GUI (button click, etc) first goes through the main initialization code before going to the specific Callback function. My thought was to put a try-catch block around the calls to gui_mainfcn. What's making me hesitate is that the code is bookended by some big old warnings:
% Begin initialization code - DO NOT EDIT
... initialization code here ...
% End initialization code - DO NOT EDIT
Could I break something by putting a try-catch block inside this initialization section? Is there a better way to attempt global error handling for a single GUI?
There is no reason that you can't insert global error handling in the main function of your GUIDE GUI. The warnings are really there to prevent people from inadvertently disrupting GUI functionality. In your case, a try/catch isn't going to actually modify the functionality so you're fine. You just want to be sure to not remove the calls to gui_mainfcn which is an internal function which contains all of the GUI logic.
Aside from that, you will also want to ensure that all requested output arguments are populated so that in the case of an error (for a function call where an output argument is expected) no error (within your catch block) is thrown because of that. That should be easy enough though
Also, I would only wrap the calls to gui_mainfcn
try
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
catch ME
% Go ahead and fill in the requested outputs with [] so we don't get an error
[varargout{1:nargout}] = deal([]);
% Do special error handling here
fprintf('Caught error: %s\n', ME.message);
end
My matlab program is a multiple window programmatic GUI. I have implemented a reporting system so when an error is encountered, it calls a function I wrote, generateReport.m, which sends an e-mail with some log and state info and then continues execution.
To accomplish this I have put a try-catch block in EVERY single function. That means even creating a wrapper for my main function. Does anybody know of a way to avoid this? I.e. being able to but a global try-catch. The reason I need multiple try-catch blocks right now is because try-catch will catch errors in functions within the block, but not sub-functions of those
Example psuedo-code:
try:
segmentImage
catch:
generateReport
end
^-- This way an error in segment-image calls generateReport, however an error in a subfunction of segment-image won't. Optimally I would only need one try-catch (or some other statement/structure I'm not aware of) in each file.
Most of the files code one GUI window each. Some are just utility.
I wrote a similar question before: matlab can't catch error in subfunction
That question asked how to use the try-catch or some function-wrapper in a callback, to implement the reporting system I have now. Before I just wanted to know why I couldn't catch errors in subfunctions. I put try-catches in every subfunction to solve that.
This question is different as I'm asking is if there's another way to do this instead of putting a try-catch in every function and subfunction which is really inconvenient and doesn't look that great. Maybe a technique I don't know about to do this or a more efficient way of structuring my code to accomplish this is needed?
Example of multiple try-catches:
First the main function I run, which just wraps CSTMainWindow
function CeleST
try
% Global try-catch on CeleST
CSTMainWindow()
catch exception
generateReport(exception)
end
Within CSTMainWindow: I have to put try-catch blocks on it's subfunctions. In this example given CSTProcessVideos and CSTCheckResults are programmatic GUI files
function processVideo(hObject,eventdata) %#ok<INUSD>
try
set(mainFigure,'Visible','off');
CSTProcessVideos
set(mainFigure,'Visible','on');
flagConsistentButton = false;
checkSequences
populateFilters
catch exception
generateReport(exception)
end
end
function checkResults(hObject,eventdata) %#ok<INUSD>
try
set(mainFigure,'Visible','off');
CSTCheckResults
set(mainFigure,'Visible','on');
flagConsistentButton = false;
checkSequences
populateFilters
catch exception
generateReport(exception)
end
end
I would like to know if there's something I could do to avoid putting a try-catch on everything (I also put the try-catch blocks on subfunctions that don't contain code written in other files)
I hope my question was clear. Thanks in advance for the help
Preliminaries. Since your application is event-driven (i.e. performs actions by callbacks) you have at least two potential sources of errors: 1) the function that builds your GUI, and then exits, 2) every callback assigned to the active UI elements.
The GUI builder. Errors in building the GUI should exit the application. Which means that your function should look like
function main(arg1, arg2, ...)
try
% test your arguments
% create the main window
% add ui elements
% register the callbacks
% create backup for application state
catch ME
generateReport(ME);
end;
end
without putting a try/catch in every helper function that is called. Since the GUI creation is faulty, the catch block should not attempt to restore the application to a (safe) default state, because there is no such default state to begin with.
The callbacks. Errors in callbacks are most likely due to wrong user input, so there is a way to rollback the application to the last known safe state:
function ui1_cbk(h, varargin)
try
% test your arguments
% perform required action
% update the backup state with the actual state
catch ME
generateReport(ME);
% restore state from last good backup
% let the user know something went wrong
end;
end
function ui2_cbk(h, varargin)
try
% ...
catch ME
% ...
end;
end;
Please note that, for UI elements that have a single callback registered to them, there is one easy way to handle all actions in a single function, thus having a single try/catch block:
function ui_general_cbk(h, varargin)
try
switch get(h, 'Tag')
case 'Tag_ui1'
% test your arguments
% perform required action
case 'Tag_ui2'
% test your arguments
% perform required action
% ...
otherwise
% ignore request
end;
% update the backup state with the actual state
catch ME
generateReport(ME);
% restore state from last good backup
% let the user know something went wrong
end;
end
Of course, for this to work, your GUI builder should assign unique (and maybe suggestive) tags to all your active UI elements.
How to generate error reports. The try/catch block could be only at the top level of the main function and the callback; to see what exactly caused the exception, one can always inspect the .stack struct array of the ME object, and—for fancy exception handling—eventually the .cause field (which would be another MException object if not empty). Like this one avoids polluting all the functions with exception handling on every level.
I need run an optimization process using fminunc for 1000 times, which means I am essentially using a for-loop to loop the optimization process 1000 times. Sometimes, I will get an error like the following:
Error using fminusub (line 16)
Objective function is undefined at initial point. Fminunc cannot continue.
or another error:
Error using chol
Matrix must be positive definite.
Now, it is obvious that these are two different type of errors and when either one of them occurs, the function will exit the for loop , which is painful for me to restart the entire process again. I am wondering whether it is possible to run a statement that try and catch all the errors and restart that single optimization process again until it runs smoothly without encountering any errors.
I just picked up matlab today and I have no idea how to do this ? Is this even possible ?
So far, this is what I have got in my mind:
try
% optimization process
fminunc(.....)
% if it fails
catch err
% regenerate a new initial values then restart optimization process
initial_para = randn(1)
fminunc(...., initial_para)
% PROBLEM is: what if it fails again in the catch statement , how can I try and catch that
end
What is particular with this code is that the only difference between the try and the catch block is that you generate new initial parameters. So what you need to do in the catch is to solve the problem. And the problem is really that you have bad initial parameters, given the code in the question. This is what you have to solve. The way you solve this is really to use a while loop that goes on until it works. So instead of creating new initial parameters and repeat the same process as in try, you should use the code you have. Else you would be forced using recursion (I really would not use a recursion of try-catch! The debugging would be really painful). Ok, but what you do: Fix the problem in catch (which means set a new initial value) and repeat the process until it works.
success = false;
while (~success)
try
% optimization process
fminunc(.....);
success = true;
catch err
% regenerate a new initial values then restart optimization process
initial_para = randn(1);
end
end
So, the code will only reach success=true if the code in the try block works. Else it will go directly to the catch block.
I wonder how a try-catch block is evaluated in matlab. In particular, is the try-catch block evaluated in runtime or "compile time"?
Also, is a try-catch block expensive?
If someone have a link to any documentation that would be much appreciated.
(Btw, I know that try-catch is not the best solution in most cases. Still I would like to know how it works, since I have used it in some code).
try and catch blocks allow you to override the default error behavior
for a set of program statements. If any statement in a try block
generates an error, program control goes immediately to the catch
block, which contains your error handling statements.
To learn more about try and catch in Matlab:Try and Catch
Try and catch block is always executed in run-time and is used to catch the errors that occur and has error-handling statements. So if your code generates some error and you want to handle it, use it. Using error-handling is good programming practice..