Skip to content

MATLAB - Error Handling

Effective error handling is crucial for writing robust, reliable, and user-friendly programs. Instead of allowing a program to crash unexpectedly, error handling allows you to anticipate potential problems, catch them gracefully, and provide meaningful feedback. This tutorial covers modern best practices for handling errors in MATLAB.

  • Syntax Errors: Mistakes in the language grammar that MATLAB’s code analyzer catches before execution (e.g., mismatched parentheses a = [1, 2) or misspelled function names disb(x)). The MATLAB Editor is excellent at highlighting these.
  • Runtime Errors: Errors that occur during code execution. These are the primary target for error handling techniques. Examples include trying to access a non-existent array element (A(10) when A has 5 elements) or dividing by zero.
  • Logical Errors: The code runs without crashing but produces an incorrect result. This is due to a flaw in the algorithm’s logic (e.g., using + instead of -). These errors cannot be caught by try/catch blocks and must be found through debugging and testing.

The try/catch Statement: The Cornerstone of Error Handling

Section titled “The try/catch Statement: The Cornerstone of Error Handling”

The try/catch statement is the fundamental mechanism for managing runtime errors. MATLAB executes the code in the try block. If an error occurs, execution immediately jumps to the catch block, skipping the rest of the try block. If no error occurs, the catch block is ignored.

filename = 'non_existent_file.csv';
try
disp('Attempting to read the file...');
% This line will throw an error
dataTable = readtable(filename);
disp('File read successfully!'); % This line will not be reached
catch ME
% The 'ME' variable is an MException object containing error details
fprintf('An error occurred!\n');
fprintf('Error Identifier: %s\n', ME.identifier);
fprintf('Error Message: %s\n', ME.message);
% You can also access the call stack to see where the error happened
% disp(ME.stack);
end
disp('Program continues after the try/catch block.');

The MException object (ME) is incredibly useful. It contains:

  • ME.identifier: A unique ID for the error (e.g., 'MATLAB:readtable:FileNotFound'). This allows you to catch specific errors.
  • ME.message: The human-readable error message.
  • ME.stack: A structure detailing the function call stack, essential for debugging complex code.

You can create and throw your own custom errors using the error or throw function. This is essential for input validation in your own functions.

function result = calculatePositiveRatio(a, b)
% This function calculates a/b, ensuring inputs are positive.
if ~isnumeric(a) || ~isnumeric(b)
% Best practice: Use a unique identifier
error('MyToolbox:InvalidInput:NotNumeric', 'Inputs must be numeric.');
end
if a <= 0 || b <= 0
error('MyToolbox:InvalidInput:NotPositive', 'Inputs must be positive values.');
end
if b == 0
% This specific case is already handled by MATLAB's Inf,
% but a custom error can be more descriptive.
error('MyToolbox:InvalidInput:DivideByZero', 'Divisor `b` cannot be zero.');
end
result = a / b;
end

Calling calculatePositiveRatio(10, -2) would halt execution and display your custom error message.

  • Use try/catch for Risky Operations: Wrap code that interacts with external resources (files, web APIs, hardware) or performs mathematically risky operations (matrix inversion) in try/catch blocks.
  • Be Specific in Your catch: You can catch specific errors by checking the ME.identifier inside the catch block. This allows you to handle different errors in different ways.
  • Use assert for Preconditions: The assert(condition, 'message') function is excellent for checking for states that should never happen in correct code. If the condition is false, it throws an error. It’s cleaner than an if statement for validating internal program state.
  • Use warning for Non-Fatal Issues: If a situation is problematic but doesn’t need to stop the program, use warning('Your message here'). For example, if a default value is being used because of invalid input.
  • Use finally for Cleanup: A try-catch block can have a third part, finally. The code in the finally block is always executed, whether an error occurred or not. This is the perfect place to put cleanup code, like closing a file handle.

Example: try-catch-finally for Safe File Handling

Section titled “Example: try-catch-finally for Safe File Handling”
fid = -1; % Initialize file identifier
try
fid = fopen('my_data.txt', 'w');
if fid == -1, error('Could not open file for writing.'); end
fprintf(fid, 'This is some data.\n');
% Let's pretend an error happens here
error('Something went wrong during processing!');
catch ME
fprintf(2, 'Caught an error: %s\n', ME.message);
finally
if fid ~= -1
fclose(fid);
disp('Cleanup complete: File handle closed.');
end
end