【问题标题】:matlab using try-catch all throughout program (global) to report errorsmatlab使用try-catch all整个程序(全局)来报告错误
【发布时间】:2015-11-12 21:00:11
【问题描述】:

我的 matlab 程序是一个多窗口编程 GUI。我已经实现了一个报告系统,所以当遇到错误时,它会调用我编写的函数 generateReport.m,它会发送一封包含一些日志和状态信息的电子邮件,然后继续执行。

为了实现这一点,我在每个函数中都放置了一个 try-catch 块。这意味着甚至为我的主要功能创建一个包装器。有人知道避免这种情况的方法吗? IE。能够进行全球尝试。我现在需要多个 try-catch 块的原因是因为 try-catch 会捕获块内函数中的错误,但不会捕获这些函数的子函数

示例伪代码:

try:
    segmentImage
catch:
    generateReport
end

^-- 这样segment-image调用generateReport中的错误,但是segment-image的子函数中的错误不会。理想情况下,每个文件中只需要一个 try-catch(或我不知道的其他语句/结构)。

大多数文件都编码一个 GUI 窗口。有些只是实用程序。 之前写过类似的问题:matlab can't catch error in subfunction

该问题询问如何在回调中使用 try-catch 或一些函数包装器来实现我现在拥有的报告系统。在我只想知道为什么我无法捕获子函数中的错误之前。我在每个子函数中都放了 try-catch 来解决这个问题。

这个问题是不同的,因为我要问的是,是否有另一种方法可以做到这一点,而不是在每个函数和子函数中都放置一个 try-catch,这真的很不方便,而且看起来不太好。也许需要一种我不知道的技术或一种更有效的方式来构建我的代码来实现这一点?

多个 try-catch 的示例: 首先是我运行的 main 函数,它只是包装了 CSTMainWindow

function CeleST
try
    % Global try-catch on CeleST
    CSTMainWindow()
catch exception
    generateReport(exception)
end

在 CSTMainWindow 内:我必须在它的子函数上放置 try-catch 块。在这个例子中,给定的 CSTProcessVideos 和 CSTCheckResults 是程序化的 GUI 文件

function processVideo(hObject,eventdata) %#ok<INUSD>
        try
            set(mainFigure,'Visible','off');
            CSTProcessVideos
            set(mainFigure,'Visible','on');
            flagConsistentButton = false;
            checkSequences
            populateFilters
        catch exception
            generateReport(exception)
        end
    end

function checkResults(hObject,eventdata) %#ok<INUSD>
    try
        set(mainFigure,'Visible','off');
        CSTCheckResults
        set(mainFigure,'Visible','on');
        flagConsistentButton = false;
        checkSequences
        populateFilters
    catch exception
        generateReport(exception)
    end
end

我想知道是否可以采取一些措施来避免对所有内容都使用 try-catch(我还将 try-catch 块放在不包含在其他文件中编写的代码的子函数上)

我希望我的问题很清楚。提前感谢您的帮助

【问题讨论】:

  • 在你之前的问题中回调的问题。现在你在谈论子函数,触发器是一个 catch 块。您能否在问题中添加一个最小示例来说明问题?

标签: matlab try-catch


【解决方案1】:

初步。 由于您的应用程序是事件驱动的(即通过回调执行操作),您至少有两个潜在的错误来源:1)构建您的 GUI 的函数,然后退出,2 ) 分配给活动 UI 元素的每个回调。

GUI 构建器。 构建 GUI 的错误应该退出应用程序。这意味着你的函数应该看起来像

function main(arg1, arg2, ...)
        try
                % test your arguments
                % create the main window
                % add ui elements
                % register the callbacks
                % create backup for application state
        catch ME
                generateReport(ME);
        end;
end

没有在调用的每个辅助函数中放置try/catch。由于 GUI 创建错误,catch 块不应尝试将应用程序恢复到(安全)默认状态,因为一开始没有这样的默认状态。

回调。回调中的错误很可能是由于用户输入错误,因此一种方法可以将应用程序回滚到最后一个已知的安全状态:

function ui1_cbk(h, varargin)
        try
                % test your arguments
                % perform required action
                % update the backup state with the actual state
        catch ME
                generateReport(ME);
                % restore state from last good backup
                % let the user know something went wrong
        end;
end

function ui2_cbk(h, varargin)
        try
                % ...
        catch ME
                % ...
        end;
end;

请注意,对于注册了单个回调的 UI 元素,有一种简单的方法可以在单个函数中处理所有操作,因此只有一个 try/catch 块:

function ui_general_cbk(h, varargin)
        try
                switch get(h, 'Tag')
                case 'Tag_ui1'
                        % test your arguments
                        % perform required action
                case 'Tag_ui2'
                        % test your arguments
                        % perform required action
                % ...
                otherwise
                        % ignore request
                end;
                % update the backup state with the actual state
        catch ME
                generateReport(ME);
                % restore state from last good backup
                % let the user know something went wrong
        end;
end

当然,要使此功能起作用,您的 GUI 构建器应该为所有活动的 UI 元素分配唯一的(可能是暗示性的)标签。

如何生成错误报告。 try/catch 块只能在main 函数和回调的顶层;要查看究竟是什么导致了异常,可以随时检查ME 对象的.stack struct 数组,以及——对于花哨的异常处理——最终是.cause 字段(如果不为空,这将是另一个MException 对象)。像这样可以避免在每个级别使用异常处理来污染所有功能。

【讨论】:

  • 正是我想要的,您的评论进一步说明了“避免污染每个级别的函数异常处理”。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-01
相关资源
最近更新 更多