错误处理 #

一、try-catch语句 #

1.1 基本语法 #

matlab
try
    % 可能出错的代码
    result = 1 / 0;
catch
    % 错误处理代码
    disp('发生错误');
end

1.2 获取错误信息 #

matlab
try
    result = 1 / 0;
catch ME
    % ME是MException对象
    fprintf('错误标识: %s\n', ME.identifier);
    fprintf('错误信息: %s\n', ME.message);
    fprintf('错误位置: %s (行 %d)\n', ME.stack(1).name, ME.stack(1).line);
end

1.3 嵌套try-catch #

matlab
try
    % 外层操作
    data = load('data.mat');
    try
        % 内层操作
        result = process(data);
    catch ME_inner
        warning('处理失败: %s', ME_inner.message);
        result = [];
    end
catch ME_outer
    error('加载失败: %s', ME_outer.message);
end

1.4 重新抛出错误 #

matlab
try
    result = risky_operation();
catch ME
    % 记录错误
    log_error(ME);
    % 重新抛出
    rethrow(ME);
end

二、错误抛出 #

2.1 error函数 #

matlab
% 简单错误
error('发生错误');

% 格式化错误
error('参数 %s 无效', param_name);

% 带标识符的错误
error('MyToolbox:InvalidInput', '输入参数必须是正数');

2.2 warning函数 #

matlab
% 简单警告
warning('这是一个警告');

% 格式化警告
warning('参数 %s 已弃用', param_name);

% 带标识符的警告
warning('MyToolbox:Deprecated', '此函数将在未来版本中移除');

% 关闭特定警告
warning('off', 'MyToolbox:Deprecated');

% 恢复警告
warning('on', 'MyToolbox:Deprecated');

2.3 assert函数 #

matlab
% 断言
x = 5;
assert(x > 0, 'x必须为正数');

% 带格式化的断言
assert(x > 0, 'x必须为正数,当前值: %d', x);

% 使用标识符
assert(x > 0, 'MyToolbox:InvalidValue', 'x必须为正数');

三、MException类 #

3.1 创建异常 #

matlab
% 创建异常对象
ME = MException('MyToolbox:InvalidInput', '输入参数无效');

% 抛出异常
throw(ME);

% 创建带原因的异常
ME = MException('MyToolbox:FileError', '无法读取文件');
ME = ME.addCause(MException('MyToolbox:FileNotFound', '文件不存在'));
throw(ME);

3.2 异常属性 #

matlab
try
    error('MyToolbox:Test', '测试错误');
catch ME
    % 标识符
    identifier = ME.identifier;
    
    % 消息
    message = ME.message;
    
    % 堆栈信息
    stack = ME.stack;
    
    % 原因链
    cause = ME.cause;
end

3.3 异常方法 #

matlab
% addCause - 添加原因
ME1 = MException('MyToolbox:Error1', '错误1');
ME2 = MException('MyToolbox:Error2', '错误2');
ME1 = ME1.addCause(ME2);

% getReport - 获取报告
try
    error('Test:Error', '测试');
catch ME
    report = getReport(ME);
    disp(report);
end

% throw - 抛出异常
ME = MException('Test:Error', '测试');
throw(ME);

% rethrow - 重新抛出
rethrow(ME);

四、自定义错误类 #

4.1 继承MException #

matlab
classdef MyException < MException
    methods
        function obj = MyException(identifier, message)
            obj@MException(identifier, message);
        end
        
        function display(obj)
            fprintf('自定义异常: %s\n', obj.message);
        end
    end
end

4.2 使用自定义异常 #

matlab
function result = my_function(x)
    if x < 0
        ME = MyException('MyToolbox:NegativeInput', '输入不能为负数');
        throw(ME);
    end
    result = sqrt(x);
end

五、输入验证 #

5.1 validateattributes #

matlab
function result = process(data)
    % 验证输入
    validateattributes(data, {'numeric'}, ...
        {'nonempty', 'vector', 'positive'});
    
    result = data * 2;
end

5.2 validatestring #

matlab
function result = process(method)
    valid_methods = {'linear', 'quadratic', 'cubic'};
    method = validatestring(method, valid_methods);
    
    switch method
        case 'linear'
            result = 1;
        case 'quadratic'
            result = 2;
        case 'cubic'
            result = 3;
    end
end

5.3 inputParser #

matlab
function result = process(data, varargin)
    p = inputParser;
    addRequired(p, 'data', @isnumeric);
    addParameter(p, 'method', 'linear', @ischar);
    addParameter(p, 'tolerance', 1e-6, @isnumeric);
    
    parse(p, data, varargin{:});
    
    result = p.Results;
end

5.4 arguments块(R2019b+) #

matlab
function result = process(data, options)
    arguments
        data (1,:) double
        options.Method (1,1) string = "linear"
        options.Tolerance (1,1) double = 1e-6
    end
    
    % 使用验证后的参数
    result = data;
end

六、调试技巧 #

6.1 断点 #

matlab
% 设置断点
dbstop in my_function at 10
dbstop if error
dbstop if warning
dbstop if error MyToolbox:InvalidInput

% 清除断点
dbclear all
dbclear in my_function

6.2 调试命令 #

matlab
% dbstep - 单步执行
dbstep
dbstep in    % 进入函数
dbstep out   % 跳出函数

% dbcont - 继续执行
dbcont

% dbquit - 退出调试
dbquit

% dbstack - 显示调用堆栈
dbstack

% dbup/dbdown - 切换堆栈层级
dbup
dbdown

% dbtype - 显示代码
dbtype my_function

6.3 条件断点 #

matlab
% 条件断点
dbstop in my_function at 10 if x > 100

七、实用示例 #

7.1 安全执行函数 #

matlab
function [result, success, message] = safe_execute(func, args)
% SAFE_EXECUTE 安全执行函数
    
    try
        result = func(args{:});
        success = true;
        message = '';
    catch ME
        result = [];
        success = false;
        message = ME.message;
        
        % 记录错误
        log_error(ME);
    end
end

7.2 错误日志 #

matlab
function log_error(ME)
% LOG_ERROR 记录错误到日志
    
    fid = fopen('error.log', 'a');
    
    fprintf(fid, '=== 错误记录 ===\n');
    fprintf(fid, '时间: %s\n', datestr(now));
    fprintf(fid, '标识符: %s\n', ME.identifier);
    fprintf(fid, '消息: %s\n', ME.message);
    
    if ~isempty(ME.stack)
        fprintf(fid, '位置: %s (行 %d)\n', ...
                ME.stack(1).name, ME.stack(1).line);
    end
    
    fprintf(fid, '\n');
    fclose(fid);
end

八、总结 #

本章学习了:

  1. try-catch:捕获和处理错误
  2. 错误抛出:error、warning、assert
  3. MException:异常对象
  4. 输入验证:validateattributes、inputParser
  5. 调试技巧:断点、调试命令

下一章将学习性能优化。

最后更新:2026-03-27