Skip to Main Content Skip to Search
File Exchange
MATLAB Newsgroup
Link Exchange
  Blogs  
 Contest 
MathWorks.com

Loren on the Art of MATLAB

October 26th, 2007

Exceptional Behavior

One of the new features of MATLAB in R2007b is a more robust way to manage and reporting errors. We have found that using an MException object, instead of relying on lasterror, has reduced one sort of coding error. The reason why the new way is better is because lasterror is a global state and can be easily corrupted. This can happen in a try/catch where you don't want to throw an error but do something else instead. However, landing in the catch updates lasterror so unless you save its state and later restore it, you may cause some unexpected behavior. In addition, MException objects allow us to readily augment the information conveyed in an error message. Let's see a little bit about how MException objects work.

Contents

try and catch E

You can generate an MException using new syntax for try/catch. As you can see in the following code, you can generate an MException object now. In the catch segment of code, you see I choose to simply display the message here.

a = [3 , 2]
b = [1 ; 7]
try
    c = a + b;
catch myEx
    disp(myEx.message)
end
a =
     3     2
b =
     1
     7
Matrix dimensions must agree.

Here's the full display of this MException.

myEx
myEx =

	MException object with properties:

    identifier: 'MATLAB:dimagree'
       message: 'Matrix dimensions must agree.'
         stack: [4x1 struct]
         cause: {}

In addition to the message, it has a message identifier, information about the calling stack, and a cause (another, often underlying MException). Get the full details on these properties here.

Adding cause

To explain more about what's happened, you can add a cause which is another MException, to the original MException. Here's another way to generate an MException.

newME = MException('Loren:Blog:MExcepExampleAddCause',...
    'Vector orientations don''t match.');
myEx = addCause(myEx,newME)
myEx =

	MException object with properties:

    identifier: 'MATLAB:dimagree'
       message: 'Matrix dimensions must agree.'
         stack: [4x1 struct]
         cause: {[1x1 MException]}

And to see the added cause, extract it.

myEx.cause{1}
ans =

	MException object with properties:

    identifier: 'Loren:Blog:MExcepExampleAddCause'
       message: 'Vector orientations don't match.'
         stack: [0x1 struct]
         cause: {}

What about error?

There is no difference currently between calling error and throwing an exception directly, since error already throws an exception internally. error is essentially implemented as:

  throw(MException(id,msg))

The reason to throw an exception directly now is to add causes.

Can You Use This Feature?

Do you see yourself using this feature in some of your applications? Post here to let me know.


Get the MATLAB code

Published with MATLAB® 7.5

17 Responses to “Exceptional Behavior”

  1. Antonio Quiroga replied on :

    Dear Loren

    I think that the introduction of MException is a quantum leap in error management in MATLAB, but, what about compatibility with previous versions? there is any planned strategy other than checking the version?

  2. Loren replied on :

    Antonio-

    It’s true for any feature that is new that it won’t work in earlier versions. Despite that, it is often possible to use it in code that straddles releases, if done judiciously. Do you have any suggestions?

    –Loren

  3. Tim Davis replied on :

    I like the new feature. It will be a great help in filtering out errors I want to catch and those I want to cause my m-file to abort.

    I write m-files that port across different versions of MATLAB using try/catch. So I do this:

    try

    use error handling here (the try/catch example above)

    catch

    oops, we must be in an old version
    use old-style try/catch. Use error instead of
    rethrow for example.

    end

    The only problem with the above pseudo-code is that it’s try/catch itself that we’re try/catching. You might mistakenly catch a real error, other than a new-syntax-in-old-MATLAB error, so it should be rethrown.

    But if used carefully, this should work.

    It would be great if there were a list, somewhere, of what features appear in each version of MATLAB, from, say, 6.1 onwards. This list would include when a function appeared (ilu first appeared in MATLAB 7.5, bsxfun in MATLAB 7.4 I think, etc.). It would also list changes in input/output arguments (’vector’ as an argument to lu, for example). It’s not easy to keep all these straight.

    I would like to see some kind of conditional try. Some errors I want to catch, others I want to not catch. Suppose I want to catch the “out-of-memory” condition (and say use another method if I do run out of memory). But if I make a silly error in my try-block (wrong dimensions, for example), I don’t want to catch that.

    I sometimes find myself commenting out the try statement, and the catch … end block, to debug my try-block. Then when it works, I uncomment the try. Kind of messy. What I do instead is first check the error in the catch block. If it’s the one I want to catch, I do the appropraite error-handling. Otherwise, I rethrow the error (actually, I use “error” since rethrow doesn’t back-port to older MATLAB’s).

  4. Loren replied on :

    Tim-

    You may get away with putting the new syntax inside a traditional try-catch block, but that won’t always work with new syntax in an older MATLAB depending on how “tight” MATLAB’s parsing had been before. With try-catch, we allowed it all on one line without a comma or semicolon after the original try in older versions and that’s why the new syntax can result in no parse error in earlier MATLABs. That won’t always be true however. Sometimes new syntax will be found plain invalid in older releases.

    –Loren

  5. Tim Davis replied on :

    Right. I see there could be a syntax problem. If I were to write code that would attempt to be portable across different versions of MATLAB, it would have to be hidden carefully. For example:

    try
    nicefunction ;
    catch
    uglyfunction ;
    end

    where nicefunction is written with the latest syntax, nifty try/catch myEX / end, and so on. Then uglyfunction would be written to try to do the same thing as nicefunction, but using the old syntax for an older MATLAB.

    Wouldn’t a syntax error insice nicefunction be caught in the try/catch, above, if an old MATLAB tried to run nicefunction but couldn’t understand the new syntax?

    It would be nice if MATLAB had a version of “version” that returned a double instead of a string, so inequalities could be tested. (”if this is MATLAB 5.x or earlier, then … else …”).

    Thanks,
    Tim

  6. Loren replied on :

    Tim-

    Check out verLessThan - it’s in recent releases of MATLAB and I believe there is a version that will run in older MATLAB releases on the File Exchange.

    –Loren

  7. Tim Davis replied on :

    verLessThan uses structs, which if I recall don’t exist in older MATLAB releases. So that function, itself, won’t port back very far. verLessThan also uses “ver”, which is about 100 times slower than “version”, if all you want is the primary MATLAB version; the run time can matter if you place a call to verLessThan in a deeply nested and heavily-used function - a likely usage.

    Before I posted my note above, I searched carefully through the File Exchange and couldn’t find any “get MATLAB version” (a search for “version” yields lots of spurious results; it would be nice to be able to limit a File Exchange search to, say, just the code in the m-files in the File Exchange).

    A little deeper digging revealed this one:

    vernum, file ID 11602

    The real question is, though, will that code work on MATLAB 1, 2, 3, 4, 5, …? How far back will it go?

    vernum also cannot distinguish between MATLAB 7.0.1 and 7.0.4 (both are “7.0″), but that’s a minor critique.

    (I realize the question of MATLAB version number may seem a bit off-topic for this blog. My reason for bringing this up is that porting to MATLAB versions is one common use that I have for try/catch).

  8. Steve Eddins replied on :

    Tim—structs go back 10 years, to MATLAB 5.0. They were introduced before try/catch.

  9. Tim Davis replied on :

    Steve: Right … which means determining the version number in, say, MATLAB 5.0 is really important - you can’t use try/catch to port code back that far. And you can’t use

    if (verLessThan (’MATLAB’,'5.0′))

    end

    because verLessThan doesn’t exist in that version. I think this would work instead, and should port to, say, MATLAB 2, even (whenever functions were introduced):

    if (getversion <= 5)
    … MATLAB 5 code here …
    else
    … etc.
    end

    where:

    function v = getversion
    v = sscanf (version, ‘%d.%d.%d’) ;
    v = 10.^(0:-1:-(length(v)-1)) * v ;

    returns 6.52 for version 6.5.2, and so on. It would return 3.2 if “version” returned a string “3.2 (whatever)”. However, the oldest MATLAB I have still running is 6.1.0 (R12.1) so I can’t test it on MATLAB 5.x or earlier.

    So how old are “version”, “sscanf”, and “length” :-) ?

  10. Steve Eddins replied on :

    Tim—Are you really interested in porting code back to run in versions ten years old or more? Like sparse linear algebra to MATLAB 3.5? :-)

  11. Tim Davis replied on :

    Well, that would be tricky, since sparse matrices didn’t exist in MATLAB until 4.0, I think (that’s also the version of MATLAB on my coffee mug “MATLAB 4 Picture the Power”).

    So sure, can I port my codes so they can run on my MATLAB 4 coffee mug? A MathWorker is a machine that turns coffee into M-files, after all (and C/C++/Java/etc), so I’m sure you’re keen to port your codes back there too … :-)

  12. Shivani Rao replied on :

    I have been trying to use the try catch block in the new version of matlab R2007a and R2007b
    I used the following syntax
    try,
    catch,

    end

    However i was unable to get this working

    try,
    catch, ME1,

    end

    It kept giving me the error “unknown identifier ME1″

    How do we get access to the exception object in this case. None of the support and dicussion forums of matlab give an example of this.

    Some help on this would be greatly appreciated

  13. Loren replied on :

    Shivani-

    Two issues. First, you are not using the syntax correctly. Check the reference page for try/catch to show how to define the MException.

    Second, perhaps you are not using the R2007b release. If not, you won’t have MExceptions available.

    —Loren

  14. k replied on :

    how try/catch can be applied for the functions for serial port? (e.g. fscanf, fprintf, and/or fopen)?

  15. Loren replied on :

    k-

    You can use try-catch with pretty much anything. For a serial port, you just need to be sure to close or delete the port if things don’t work out.

    –Loren

  16. k replied on :

    Thank you very much. Could I ask some more in detail, please?
    For example, repeat ‘fscanf’ for 50 loops, but Matlab may cause a “timeout” error. I am not sure what I should put in the “catch” statement. (fclose and fopwn again here?)

    try,
    for 1+1:1:50,
    measure = fscanf(s);
    end
    catch
    end

  17. Loren replied on :

    k,

    Please contact technical support for more information. This is not an issue with try-catch or exceptions, the topic of the post.

    –Loren

Leave a Reply


Loren Shure works on design of the MATLAB language at The MathWorks. She writes here about once a week on MATLAB programming and related topics.

  • Ulla Vainio: That error bar width adjustment was extremely useful and I would never have figured it out myself....
  • Peter Perkins: Jessee, there is a property that you can use to tag variables with units. For example, >> load...
  • Jessee: I could potentially see myself using dataset for casually looking at data, but from an application standpoint...
  • Loren: Oktay- It very much depends on the details of the calculations you are doing. Vectorization can sometimes...
  • Oktay: Hello, Is there any significant difference between using: - Vectorization inside a subfunction - Benefiting...
  • Loren: Clare- Yes, sum can sum a double vector: x = [.3 .4 pi/3] y = sum(x) x = 0.3 0.4 1.0472 y = 1.7472 You must...
  • Clare J: R2007a - Student Version When I use sum to sum a vector of type double I get this error message: ???...
  • Sarah Zaranek: Hi Jacob, Sorry about the slow response. You are correct that the code would be slower without the...
  • Navaneethan Santhanam: Thanks a lot, Loren! That worked perfectly.
  • Mike N: Should it be OK to use “persistent 221; variables in a deployed application? What if I have two...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.

Related Topics