A not-well-known performance improvement trick for catching errors is to place the entire code section within a try-catch block. This is more efficient than constantly checking for some condition. For example:
% Standard code for loopIndex = 1 : N refIndex = someCalculation(); if refIndex > 0 A(loopIndex) = B(refIndex); else A(loopIndex) = loopIndex; end end % Faster code for loopIndex = 1 : N refIndex = someCalculation(); try A(loopIndex) = B(refIndex); catch A(loopIndex) = loopIndex; end end
Trapping warnings
However, what should we do in case the checked condition is meant to prevent a warning (e.g., file-access warnings) rather than an error? It would make sense to use the same exception-handling trick, but unfortunately warnings do not normally raise a trappable exception. This question was asked on the CSSM newsgroup many years ago and received no answer, until Michael Wengler recently provided the undocumented solution on that thread:
It appears that in addition to the documented alternatives for the value of the warning function’s first parameter (namely ‘Message’,
For example:
% Set a couple of warnings to temporarily issue errors (exceptions) s = warning('error', 'MATLAB:DELETE:Permission'); warning('error', 'MATLAB:DELETE:FileNotFound'); % Run the processing section filesList = {'a.doc', 'b.doc', 'c.doc'}; for fileIndex = 1 : length(filesList) try % Regular processing part fileToDelete = filesList{fileIndex}; delete(fileToDelete); catch % Exception-handling part fprintf('Can''t delete %s (reason: %s)\n', fileToDelete, lasterr); end end % Restore the warnings back to their previous (non-error) state warning(s);
For the record, this warning(‘error’,…) trick appears to work in Matlab releases as far back as R14SP3 (2005), and possibly even earlier (I don’t have older releases readily available, so I couldn’t check). This looks like a pretty stable feature, as far as undocumented features go. Of course, it could well be taken out at any future Matlab release, but for the time being we can definitely make good use of it.
Trapping specific warning IDs
How can we know the specific warning IDs (e.g., ‘MATLAB:DELETE:FileNotFound’) to use? The answer is to call warning(‘on’,'verbose’) and then simulate the warning. For example:
>> warning on verbose >> delete sadfsefgsdfg Warning: File 'sadfsefgsdfg' not found. (Type "warning off MATLAB:DELETE:FileNotFound" to suppress this warning.)
Within the exception-handling part, we could check the specific exception that was thrown and possibly act differently. For example:
try % Regular processing part fileToDelete = filesList{fileIndex}; delete(fileToDelete); catch % Exception-handling part err = lasterror; switch identifier case 'MATLAB:DELETE:Permission' fprintf('Can''t delete %s (reason: no permission)\n', fileToDelete); case 'MATLAB:DELETE:FileNotFound' fprintf('Can''t delete %s (reason: file not found)\n', fileToDelete); otherwise fprintf('Can''t delete %s (reason: %s)\n', fileToDelete, lasterr); end end
Note that within the exception-handling part, I used the lasterr and lasterror functions, rather than lastwarn. The reason is that the warnings have been converted into standard errors, and are no longer even reported by lastwarn.
The acute reader will have noticed that I am using the older (deprecated) manner of exception handling, that does not directly pass the error struct into an identifier next to the catch keyword. The reason is that I usually intend my code to be backward compatible. Had I used the newer syntax, the code would not have worked on old Matlab releases; this way it does, subject to the availability of the above-mentioned undocumented warning(‘error’,…) trick. If you read through the code of my numerous submissions on the File Exchange, you will see that this is a recurring theme. I often use old deprecated syntax to ensure that my code will run on as many Matlab releases as possible.
Are you interested in learning more performance improvement methods? Then consider joining my Matlab Performance Tuning seminar/workshop in Geneva on August 21, 2012 – email me (altmany at gmail dot com) for details.
Related posts:
- Undocumented scatter plot behavior The scatter plot function has an undocumented behavior when plotting more than 100 points: it returns a single unified patch object handle, rather than a patch handle for each specific point as it returns with 100 or less points....
- Parsing mlint (Code Analyzer) output The Matlab Code Analyzer (mlint) has a lot of undocumented functionality just waiting to be used. ...
- More undocumented timing features There are several undocumented ways in Matlab to get CPU and clock data...
- UDD Events and Listeners UDD event listeners can be used to listen to property value changes and other important events of Matlab objects...
- Creating a simple UDD class This article explains how to create and test custom UDD packages, classes and objects...
- xlsread functionality change in R2012a The functionality of the xlsread function has changed without documentation or warning in the R2012a release. ...


Hello,
Very informative post. I found a bug in the code in the ‘Trapping warnings block’: you initialize your counter with filesIndex = 1, but index with filesList{fileIndex}. There is a mismatch between filesIndex and fileIndex (i.e. one is plural and the other is singular).
Best,
John
@John – thanks, corrected
Hi there, I have tried to use your template above to do my own error trapping. However, I have found some rather strange behavior. When I run the code as shown below, the code runs and delivers the correct results. However when I %matlabpool open, %matlabpool close and change parfor to a simple for, the code will not run and I get the following error:
Now I am not surprised to be getting the error, this is the result of the
I included (there is not try catch yet included yet in the function DElambda). What confuses me though it why when I run this code as part of a parallel loop no errors are generated? Do trapping warnings work with parfor?
@Baz – apparently this only works in a non-distributed environment…
Thanks, the reason I am doing the coding this way is that rdivide is generating these error messages when it enounters a singular/badly conditioned matrix, so rdivide is clearly already using rcond() to test the conditioning of the matrices. I need to check the conditioning of the matrices, rather than me having to call rcond() again to duplicate this work, I would just like to get access to the rcond values and/or the decision as to whether the matrix is badly conditioned or not that rdivide is already producing. Ideally within a parallel structure if this is possible?
To be clear the parallel toolbox does still produce these warning messages, its just when I add:
to turn them into errors that the divergence between parfor and for arises.
Would I be better to just call rcond() myself, this will mean duplication of work (which is annoying), but as least it will work.