COMP 5115 Programming Tools in Bioinformatics Week 8

raviolirookeryBiotechnology

Oct 2, 2013 (3 years and 9 months ago)

131 views

Error Handling


In many cases, it is desirable to take specific actions when different kinds
of errors occur. The error handling capabilities in MATLAB let an
application check for particular error conditions and execute appropriate
code depending on the situation.


Checking for errors with try
-
catch
: Checking for errors that occur in your
programs using the try and catch functions

Handling and recovering from an Error
: Reporting errors and identifying
what caused them; regenerating errors

Message identifiers
: Attaching an identifier to an error or warning to
enable you to better identify what caused it, and also for selective
warning control

Warnings
: Identifying warnings and identifying what caused them

Warning control
: Controlling the action taken when a warning is
encountered

Debugging errors and warnings
: Stopping code execution in the
debugger on the occurrence of an error or warning

COMP 5115 Programming Tools in Bioinformatics

Week 11

Checking for Errors with try
-
catch


No matter how carefully you plan and test the programs you write, they
may not always run as smoothly as expected when run under different
conditions.

It is always a good idea to include error checking in programs to
ensure reliable operation under all conditions.


When you have statements in your code that could possibly generate
unwanted results, put those statements into a
try
-
catch block

that will
catch any errors and handle them appropriately.


Example: A try
-
catch block within a sample function that multiplies two
matrices:



function matrixMultiply(A, B)


try



X = A * B


catch



disp '** Error multiplying A * B'


end

Checking for Errors with try
-
catch (cont.)

-
A try
-
catch block is divided into two sections. The first begins with
try

and the second with
catch
. Terminate the block with
end
.


-
All statements in the try segment are executed normally, just as if they
were in the regular code flow. But if any of these operations results in an
error, MATLAB skips the remaining statements in the try and jumps to
the catch segment of the block.


-
The catch segment handles the error. In this example, it displays a
general error message. If there are different types of errors that can
occur, you will want to identify which error has been caught and respond
to that specific error. You can also try to recover from an error in the
catch section.


-
When you execute the above example with inputs that are incompatible
for matrix multiplication (e.g., the column dimension of A is not equal to
the row dimension of B), MATLAB catches the error and displays the
message generated in the catch section of the try
-
catch block.


A = [1 2 3; 6 7 2; 0 1 5];


B = [9 5 6; 0 4 9];


matrixMultiply(A, B)


** Error multiplying A * B


-
Faulty
error

statements executed within a try block are not caught, but
instead cause MATLAB to abort the M
-
file.

Nested try
-
catch Blocks



-
try
-
catch blocks

can also be nested for checking errors if any.


-
Nested try
-
catch blocks

can be used to attempt to recover from an
error caught in the first try section:


-
Example:



try



statement1


% Try to execute statement1


catch



try





statement2


% Attempt to recover from error



catch




disp 'Operation failed'

% Handle the error



end


end



Handling and Recovering from an Error


The catch segment of a try
-
catch block needs to effectively handle any
errors that may be caught by the preceding try. Frequently, you will want
to simply report the error and stop execution. This prevents erroneous
data from being propagated into the remainder of the program.


Reporting an Error
: To report an error and halt program execution, use
the MATLAB
error

function. You determine what the error message will
be by specifying it as an input to the error function in your code.



Example
:




if n < 1




error('n must be 1 or greater.')



end



displays the message shown below when n is equal to zero.




??? n must be 1 or greater.



Handling and Recovering from an Error


Formatted Message Strings:
The error message string that you specify
can also contain formatting conversion characters, such as those used
with the MATLAB
sprintf

function. Make the error string the first
argument, and then add any variables used by the conversion as
subsequent arguments.



error('
formatted_errormsg
', arg1, arg2, ...)


For example, if your program cannot find a specific file, you might report
the error with



error('File %s not found', filename);


Message Identifiers:
Use a
message identifier

argument with error to
attach a unique tag to that error message. MATLAB uses this tag to
better identify the source of an error. The first argument in this example is
the message identifier.



error('MATLAB:noSuchFile', 'File "%s" not found', filename);

Handling and Recovering from an Error


Formatted String Conversion
: MATLAB converts special characters
(like
\
n and %d) in the error message string only when you specify more
than one input argument with error.


The single
-
argument case:
\
n is taken to mean backslash
-
n. It is not
converted to a newline character.



error('In this case, the newline
\
n is not converted.')


??? In this case, the newline
\
n is not converted.


More than one argument case: MATLAB does convert special
characters. This is true regardless of whether the additional argument
supplies conversion values or is a message identifier.



error('ErrorTests:convertTest', ...



'In this case, the newline
\
n is converted.')


??? In this case, the newline


is converted.

Handling and Recovering from an Error

Identifying the Cause


Once an error has been caught, you will need to know the source of the
error in order to handle it appropriately.


The
lasterror

function returns information that enables you to identify the
error that was most recently generated by MATLAB.


Example
: add a call to lasterror, and then display the information that is
returned:


function matrixMultiply(A, B)


try



X = A * B


catch


disp '** Error multiplying A * B'


err = lasterror;



fprintf('
\
nInformation on the last error:
\
n
\
n')


fprintf(' Message: %s
\
n
\
n', err.message)


fprintf(' Identifier: %s
\
n
\
n', err.identifier)


errst = err.stack;


fprintf(' Failed at
\
n')


fprintf(' Line %d
\
n', errst.line)


fprintf(' Function %s
\
n', errst.name)


fprintf(' File %s
\
n', errst.file)


end

Handling and Recovering from an Error

Identifying the Cause
(cont.)

lasterror returns a structure containing the text of the most recent error
message, the message identifier for that error, and information from the
stack regarding the error.


The message and identifier fields of the return structure are strings; the
stack field is a structure with fields file, name, and line, to identify the file,
function, and line number of the failing line of code:



matrixMultiply([16 24], [6 15])


** Error multiplying A * B



Information on the last error:



Message: Error using ==> mtimes


Inner matrix dimensions must agree.



Identifier: MATLAB:innerdim


Failed at


Line 3 Function matrixMultiply


File d:
\
matlab_test
\
matrixMultiply.m


You can also change the text of the last error message with a new
message or with an empty string as shown below. You might want to do
this if a lower
-
level routine detects an error that you don't want visible to
the upper levels.

Handling and Recovering from an Error

Identifying the Cause
(cont.)


lasterror returns a structure containing the text of the most recent error
message, the message identifier for that error, and information from the
stack regarding the error.


The message and identifier fields of the return structure are strings; the
stack field is a structure with fields file, name, and line, to identify the file,
function, and line number of the failing line of code:



matrixMultiply([16 24], [6 15])


** Error multiplying A * B



Information on the last error:






Message: Error using ==> mtimes


Inner matrix dimensions must agree.



Identifier: MATLAB:innerdim


Failed at


Line 3 Function matrixMultiply


File d:
\
matlab_test
\
matrixMultiply.m

Handling and Recovering from an Error

Identifying the Cause
(cont.)


You can also change the text of the last error message with a new
message or with an empty string as shown below. You might want to do
this if a lower
-
level routine detects an error that you don't want visible to
the upper levels.


Replace last error message with a new string:



err.message = ['The number of columns of one input must ' ...




'equal the number of rows of the other.'];


lasterror(err);


Replace last error message with an empty string:



lasterror('reset');

Identifying the Cause
(cont.)

Example Using lasterror:
This example uses lasterror to determine the cause of
an error in the example matrixMultiply function:


function matrixMultiply(A, B)

try


A * B

catch


err = lasterror;


if(strfind(err.message, 'Inner matrix dimensions'))



disp('** Wrong dimensions for matrix multiply')


else



if(strfind(err.message, 'not defined for values of class'))




disp('** Both arguments must be double matrices')



end


end

end


When calling the function with two matrices not compatible for matrix
multiplication, you get the following error message:


A = [1 2 3; 6 7 2; 0 1 5];


B = [9 5 6; 0 4 9];


matrixMultiply(A, B)


** Wrong dimensions for matrix multiply



When calling the function with a cell array argument, you get a message that
addresses that error:


C = {9 5 6; 0 4 9};


matrixMultiply(A, C)


** Both arguments must be double matrices

Message Identifiers


A message identifier is a tag that you attach to an error or warning
statement that makes that error or warning uniquely recognizable by
MATLAB. You can use message identifiers with error reporting to better
identify the source of an error, or with warnings to control any selected
subset of the warnings in your programs.


Identifier Format
: The message identifier is a string that specifies a
component

and a
mnemonic

label for an error or warning. A simple
identifier looks like this:


component:mnemonic

Some examples of message identifiers are


MATLAB:divideByZero


Simulink:actionNotTaken


TechCorp:notFoundInPath

Both the component and mnemonic fields must adhere to the following
syntax rules:


No white space (space or tab characters) is allowed in the entire identifier.


The first character must be alphabetic, either uppercase or lowercase.


The remaining characters can be alphanumeric or underscore.


There is no length limitation to either field.

Component Field
: The component field of a message identifier specifies
a broad category under which various errors and warnings can be
generated. Common components are a particular product or toolbox
name, such as MATLAB or Control, or perhaps the name of your
company, such as TechCorp in the example above.


You can also use this field to specify a multilevel component. The
statement below has a three
-
level component followed by a mnemonic
label:


TechCorp:TestEquipDiv:Waveform:obsoleteSyntax

One purpose of the component field is to enable you to guarantee the
uniqueness of each identifier. Thus, while MATLAB uses the identifier
MATLAB:divideByZero for its 'Divide by zero' warning, you could reuse
the divideByZero mnemonic by using your own unique component. For
example,


warning('TechCorp:divideByZero', 'A sprocket value was divided

by zero.')


Mnemonic Field
: The mnemonic field is a string normally used as a tag
relating to the particular message. For example, when reporting an error
resulting from the use of ambiguous syntax, a mnemonic such as
ambiguousSyntax might be appropriate:



error('MATLAB:ambiguousSyntax', …



'Syntax %s could be ambiguous.
\
n', inputstr)

Using Message Identifiers with lasterror


One use of message identifiers is to enable the
lasterror

and
lasterr

functions to better identify the source of an error. These functions return
a message identifier, and you can use the combination of component and
mnemonic parts of that identifier to identify both a broad category of
errors and a specific instance within that category, respectively.


The first step in using this feature is to determine which of your error
messages need this type of identification and then tag each with an
identifier. You do this by specifying a message identifier argument
(msg_id, below) along with the error message in your calls to
error
. Either
form shown below is acceptable. The latter form uses formatting
conversion characters as described in
Formatted Message Strings
.



error('msg_id', 'errormsg')


error('msg_id', 'formatted_errormsg', arg1, arg2, ...)


The message identifier must be the first argument and must be formatted
according to the rules covered in
Message Identifiers
.

The message identifier is not a required argument for error. If you use
lasterror in a manner that does not make use of this information, you can
omit the
msg_id

argument from the error function syntax shown
previously:


error('errormsg')

Using Message Identifiers with lasterror (con.t)


Returning a Message Identifier from lasterror
: The structure returned
by the lasterror function has three fields:


message
--

Text of the error message


identifier
--

Message identifier tag


stack
--

Information about the error from the program stack

Inputs to lasterror
: In addition to returning information about the last
error,
lasterror

also accepts inputs that modify the MATLAB copy of the
last error.


Warnings


Like error, the
warning

function alerts the user of unexpected conditions
detected when running a program. However, warning does not halt the
execution of the program. It displays the specified warning message and
then continues.

Reporting a Warning
: Use warning in your code to generate a warning
message during execution. Specify the message string as the input
argument to warning. For example,


warning('Input must be a string')


Warnings also differ from errors in that you can disable any warnings that
you don't want to see.

Warnings (cont.)


Formatted Message Strings:
The warning message string that you
specify can also contain formatting conversion characters, such as those
used with the MATLAB
sprintf

function. Make the warning string the first
argument, and then add any variables used by the conversion as
subsequent arguments.


warning('
formatted_warningmsg
', arg1, arg2, ...)

For example, if your program cannot process a given parameter, you
might report a warning with


warning('Ambiguous parameter name, "%s".', param)

MATLAB converts special characters (like
\
n and %d) in the warning
message string only when you specify more than one input argument
with warning.


Message Identifiers:
Use a
message identifier

argument with warning to
attach a unique tag to that warning message. MATLAB uses this tag to
better identify the source of a warning. The first argument in this example
is the message identifier.


warning('MATLAB:paramAmbiguous', ...



'Ambiguous parameter name, "%s".', param)


Warnings (cont.)


Identifying the Cause
: The
lastwarn

function returns a string containing
the last warning message issued by MATLAB. You can use this to enable
your program to identify the cause of a warning that has just been issued.


To return the most recent warning message to the variable warnmsg,
type


warnmsg = lastwarn;


You can also change the text of the last warning message with a new
message or with an empty string as shown here:



lastwarn('newwarnmsg'); % Replace last warning with new string

lastwarn(''); % Replace last warning with empty string


Warning Control
: MATLAB gives you the ability to control what happens
when a warning is encountered during M
-
file program execution. Options
that are available include


Display selected warnings


Ignore selected warnings


Stop in the debugger when a warning is invoked


Display an M
-
stack trace after a warning is invoked

Warning Control (cont.)
: Depending on how you set up your warning
controls, you can have these actions affect all warnings in your code,
specific warnings that you select, or just the most recently invoked
warning.


Setting up this system of warning control involves several steps:


1.
Start by determining the scope of the control you will need for the
warnings generated by your code. Do you want the above control
operations to affect all the warnings in your code at once, or do you
want to be able to control certain warnings separately?


2. If the latter is true, you will need to identify those warnings you want to
selectively control. This requires going through your code and attaching
unique
message identifiers

to those warnings. If, on the other hand, you
don't require that fine a granularity of control, then the warning
statements in your code need no message identifiers.


3. When you are ready to run your programs, use the MATLAB warning
control statements to exercise the desired controls on all or selected
warnings. Include message identifiers in these control statements when
selecting specific warnings to act upon.