我的matlab程序是一个多窗口程序化GUI。我已经实现了一个报告系统,所以当遇到错误时,它会调用我编写的函数generateReport.m,它发送一个带有一些日志和状态信息的电子邮件,然后继续执行。
为了实现这一点,我在每个单独的函数中都放了一个try-catch块。这意味着甚至为我的main函数创建一个包装器。有人知道避免这种情况的方法吗?即能够进行全球尝试。我现在需要多个try-catch块的原因是因为try-catch会捕获块中函数的错误,而不是那些
的子函数psuedo-code示例:
try:
segmentImage
catch:
generateReport
end
^ - 这样,段映像中的错误会调用generateReport,但是段映像的子函数中的错误不会。最理想的是,我只需要在每个文件中使用一个try-catch(或其他一些我不知道的语句/结构)。
大多数文件各自编码一个GUI窗口。有些只是效用。 我之前写了一个类似的问题:matlab can't catch error in subfunction
该问题询问如何在回调中使用try-catch或一些函数包装器来实现我现在的报告系统。之前我只想知道为什么我无法捕捉到子功能中的错误。我在每个子功能中都设置了try-catch来解决这个问题。
这个问题是不同的,因为我问的是,是否还有另一种方法可以做到这一点,而不是在每个功能和子功能中放置一个try-catch,这真的很不方便,看起来不那么好。也许需要一种我不知道要做的技术,还是需要一种更有效的方法来构建我的代码来实现这一目标?
多次尝试捕获的示例: 首先是我运行的主要功能,它只包含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块放在不包含其他文件中编写的代码的子函数中)
我希望我的问题很明确。在此先感谢您的帮助
答案 0 :(得分: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
函数和回调的顶层;要查看确切导致异常的原因,可以始终检查.stack
对象的ME
struct数组,并且 - 用于花哨的异常处理 - 最终.cause
字段(这将是另一个{ {1}}对象,如果不是空的)。像这样可以避免在每个级别上使用异常处理来污染所有函数。