이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
How to obtain an MException in a cleanup function
조회 수: 8 (최근 30일)
이전 댓글 표시
Matt
2020년 10월 26일
Hi all,
I've noticed that "lasterror" indicates that it will be obsolete soon, and MException.last indications that it can only be used from the command line. Without using a try/catch construct in the calling/parent function that is being cleaned up, is there any good way to check to see if the calling function being cleaned up generated an error?
댓글 수: 14
Adam Danz
2020년 10월 26일
Wouldn't the dbstack or the 'stack' field of the MException list what you're looking for?
Matt
2020년 10월 26일
Hi Adam,
The question here is how to obtain the last MException now that lasterror is being obsoleted. Once it is obtained, yes, the stack field is very useful.
Bruno Luong
2020년 10월 26일
TMW recommends using try/catch to get the error. What is the reason to prevent you to follow their recommendation?
Matt
2020년 10월 26일
Hi Bruno,
- TMW also recommends onCleanup for error handling. Having to do a try catch as well as onCleanup is undesirable. In this case no error handling is being done beyond logging.
- Specifically try/catch and rethrows change how the debugger handles exceptions in undesirable ways. If there was a good way to use dbstop if caught error, this wouldn't be as necessary, but given its current unusablility finding a workaround without try/catch is important.
This is way beyond the scope of the question, but if there was a way to limit dbstop if caught error to non-built in functions, it would be much more useful. Currently if I set it, I get a caught exception within one second of setting it without even running any code. Something about device plugins in a toolbox library. But even when it behaves "normally", there are too many exceptions in the built in libraries to use dbstop if caught error without a lot of constant frustration/time waste.
Bruno Luong
2020년 10월 26일
편집: Bruno Luong
2020년 10월 26일
"Having to do a try catch as well as onCleanup is undesirable"
Why?
I never though they usage must be exclusive. In fact they do different things. I usually use them like this:
- onCleanup performs clean-up tasks, usulally implemented in the calling function, it implements the tasks that must be carried-out where as the function terminates normally or terminates because of and error; and
- try/catch is on the caller, to ignore/log/display a warning message if error occurs in the calling function, and eventually branch to different part of the code.
So I never wonder for onCleanup to knows whereas error occurs and what kind of error. That's the job of try/catch.
Now if you don't wan't to use both, then I would say, too bad for you to limit yourself with such constraint.
DBSTOP is for debugging, this is another topic in my book. I'm not sure I understand your description of the inconvenient of debugging flow and exception handling in regular flow of the code.
Rik
2020년 10월 26일
I'm a bit concerned about the removal of lasterror. I want my code to be compatible with Matlab 6.5 (R13), because it is lightning fast in some situations. If lasterror is removed I will be forced to use this mess:
ME='initialise ME as char';
try
something_that_may_error
catch ME; %#ok<NOSEL>
% ^ suppress output in case of ML6.5 (and add the %#ok pragma for mlint)
if isa(ME,'char'),ME=lasterror;end %#ok<LERR>
end
Adam Danz
2020년 10월 26일
편집: Adam Danz
2020년 10월 26일
Using onCleanup will not prevent the error from being thrown.
For example,
cleanup = onCleanup(@()disp(dbstack()));
t = 5 * randi(100);
z = t+x; % x is not defined; hence, error.
Unrecognized function or variable 'x'.
So it's still not clear to me what the use case is here.
Matt
2020년 10월 26일
@Bruno,
Its not just aesthetics. Try/Catch changes the debuggers behavior, so if you don't want to do that (debugger behavior can be fairly important in some frameworks for executing other code), but still want to detect that an error occured, then lasterror has a distinct and useful purpose.
Bruno Luong
2020년 10월 26일
편집: Bruno Luong
2020년 10월 26일
try
dosomebuggycode
catch ME
rethrow(ME) % <- here you have you error code, and debugger stops here is wished
% you can also comment temporary try/catch during debugging
% please explain why it doesn't fit your need???
% how lasterror() can help you more than this???
end
Matt
2020년 10월 27일
편집: Matt
2020년 10월 27일
Here's some pseudocode with an example demonstrating the utility of lasterror to maintaining a natural debug environment.
function myNiceFunction(usersBuggyFunctionHandle)
onCleanup(@myNiceOnCleanup)
%Do Some setup
outputData = usersBuggyFunctionHandle() %<--- User needs to be able to natively debug this with dbstop if error
%onCleanup currently lets me log errorData here - without a try catch
end
function myNiceOnCleanup
logErrorData(lasterror) %<--- On Cleanup log the error data if its available
end
Steven Lord
2020년 10월 27일
In the pattern you describe, a try / catch block would be my choice of approaches to use. You only want to log the error data if an error actually occurs and you only want to log the error if it comes from the scope of your function. As written your myNiceOnCleanup function will always get executed, error or no error. In addition there's a chance (albeit a slim one) it could catch an error from a timer object's TimerFcn, a Handle Graphics callback function, etc. [I'm not sure offhand how or if lasterror interacts with a parallel.ThreadPool but I wouldn't be surprised if "complicated" appears more than once in the answer.]
function myNiceFunction(usersBuggyFunctionHandle)
%Do Some setup
try
outputData = usersBuggyFunctionHandle();
%<--- User needs to be able to natively debug this with dbstop if error
catch errorData
myNiceOnCleanup(errorData)
end
end
function myNiceOnCleanup(errorData)
% Process the MException
logErrorData(errorData)
rethrow(errorData) % or throwAsCaller
end
As for debugging this, if an error occurs the user can set a breakpoint on the line inside the catch where myNiceOnCleanup is called. Or maybe this function accepts an optional input and you have a section in your code that calls keyboard if it is specified.
Matt
2020년 10월 27일
Thanks Steven, and everyone else for all the input. It is much appreciated.
I understand the try/catch approach. The issue is that the try/catch approach takes twice as long to debug because to debug it you have to run it twice - once to find out its going to crash, and once with a debug point in. When you have code that takes hours to execute, this is a non-starter.
Long story short, try/catch is not useable for this usecase. When lasterror is obsoleted, I'll probably need to remove the error logging rather than doubling the amount of time it takes to do debugging. This question was aimed at finding a way to not do that.
Steven Lord
2020년 10월 27일
If you want to unconditionally stop in the catch block, add a call to keyboard.
Matt
2020년 10월 28일
편집: Matt
2020년 10월 28일
Hi Steven, the two needed behaviors (in order of importance) are
1) To unconditionally stop where a crash occurs (or at least in the same workspace), when the crash occurs, the first time the crash occurs. This is doable with dbstop if error if there isn't a try/catch statement. Try catch doesn't support it.*
2) Log exceptions when they occur. Currently the lasterror function allows a flawed but useable implementation of this.
*Try catch doesn't support this because keyboards or rethrows will cause the debugger to stop in the workspace where the try/catch block is, not where the exception originally occured in the users code. dbstop if caught error does nominally supports this, but as I mentioned above its really not useable in its current state because it catches exceptions in the try/catch blocks in built in code.
답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Debugging and Analysis에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
아시아 태평양
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)