Save output error messages to file in MATLAB - matlab

Is there a way to save MATLAB error messages to a file?
This may be a simple issue, but Google couldn't give me an answer. I've compiled a GUI executable for use without a MATLAB license, and occasionally it freezes. For aesthetic purposes, I suppressed the command window normally accompanying such an executable, so I can't get an error message out through the command prompt. I'd like to be able to create an error log which can be emailed to me for debugging.
Thanks!

Use try...catch statements around the code. In the catch block, you can write out the error including stack information. Using sendmail, you can even have the code notify you of errors by mail (ideally with a popup that lets users decide whether they want to share the crash information with you)
try
% your code here
catch err
%open file
fid = fopen('logFile','a+');
% write the error to file
% first line: message
fprintf(fid,'%s\n',err.message);
% following lines: stack
for e=1:length(err.stack)
fprintf(fid,'%sin %s at %i\n',txt,err.stack(e).name,err.stack(e).line);
end
% close file
fclose(fid)
end
Edited to be a bit more explicit on how to write error message to file

Use the "diary" command to create a log file. This will make Matlab write a copy of all the command line output to a file, including warnings, error messages, and the stack traces for unhandled exceptions. Sendmail() can then send it to you on errors. If you want to save space, you can have the program delete its log file on a normal (no error) program exit.
IMHO this is preferable to using the "try ... catch; write errors; end" because:
It will capture all uncaught errors, including Java exceptions raised from the AWT thread and errors from M-code callbacks in your GUI, which can be hard to get try/catches around.
If Matlab is crashing hard, like with a segfault, the M-code level try/catch won't catch it. But the diary file may still record the segfault dump.
You can emit progress messages, debug info, and warnings to give more information on your program's behavior leading up to the errors, and they'll all be captured.
I like to keep code in catch blocks minimal.
There's also a command line option that does the equivalent; I don't know how to invoke that for compiled Matlab.

For older versions of MATLAB you can use the LASTERROR function to get information about the most recent error issued by MATLAB. However, this function will be phased out in newer MATLAB versions.
For newer versions of MATLAB, I would suggest making use of the MException class to capture error information. You can catch an MException object using a try-catch block as Jonas suggested, or you could potentially use the static MException.last method to get the last uncaught exception (depending on how you run your code):
%# OPTION 1:
%# --------
try
my_code();
catch ME
%# Save data in ME to file
end
%# OPTION 2:
%# --------
my_code();
ME = MException.last;
%# Save data in ME to file
Whichever way you capture the MException object, you can use the MException.getReport method to display a formatted message string including the information contained in the MException object:
msgString = getReport(ME,'basic'); %# Displays the higher level error
msgString = getReport(ME,'extended'); %# Displays the error and the stack
You can then write the message string to a file.

try
% your code here
catch err
fid = fopen('errorFile','a+');
fprintf(fid, '%s', err.getReport('extended', 'hyperlinks','off'))
fclose(fid)
end

For exact formatting style like from Matlab command window, use:
rep = getReport(exception, 'extended', 'hyperlinks', 'off');
name = strcat('Data\', name, '.txt');
fid = fopen(name, 'w+t','n');
fprintf(fid, 'Error message\n-------------\n\n');
fprintf(fid, '%s\n', rep);
fclose('all');

Related

Warning: Unable to load Toolbox Path Cache in a for loop

I have a code that is like this
echo "try;
start=tic;
sv=fopen('$SIZE_VECTOR_1','r');
vector=fscanf(sv, '%d');
fclose(sv);
tama=fopen('$TAMANO_EVAL','r');
taman=fscanf(tama, '%d');
fclose(tama);
fid=fopen('$LISTA_WORDS_EVAL','r');
lista=fscanf(fid,'%f',[taman,vector]);
fclose(fid);
v_writehtk('${OUT_DIR_FEA_EVAL}/${name}.fea',lista,0.01,6);
toc(start)
catch
disp('THROWN MATLAB ERROR:');
e=lasterror;
disp(e);
e.message
e.stack.file
e.stack.name
e.stack.line
end
" > ${OUT_DIR_VEC_EVAL}/${M_FILE}.m;
I have to do this matlab code multiple times in a loop with different values, It is a "for loop" that takes different files with different names, so the for loop is in my shell script code and at each loop this matlab code is created in a txt file and then executed by matlab, I am not doing it in parallel. v_writehtk is a matlab code that transform the files taked by the loop and transforms it to another format.
sometimes in the loop I receive the Warning: Unable to load Toolbox Path Cache , so I want to know whether or not this affect to my results and how can I solve this?, I tried things like "exit" at the end of the code or "rehash toolboxcache" at the beginning and end of the code but I keep receiving this warning sometimes. Please someone help me on this.

Running an interactive Matlab .m file with a batch call

I have a Matlab .m file that I usually run interactively. I would like to run some jobs overnight, WITHOUT re-writing the .m file to remove the interactive queries for input. I used to be able to do this with Fortran or C or VB executables by running a batch file from the OS's command line. Is this possible with Matlab? (Also, I don't have the Matlab compiler. But I can have Matlab open the whole time.)
Skeleton of Program:
Input variable1 from keyboard;
Input variable2 from keyboard;
Long calculation;
Save results to file;
Stop
But, if I make a "batch" .m file to run Program, like this:
Program
0.2
0.47
Program
1.2
2.4
then Program just sits there forever waiting for my input from the keyboard. Is there a way to run Program so that it gets its interactive inputs from the calling .m file?
What environment/operating system are you working on? You refer to a batch file which leads one to think you are working in Windows. If you are working in Linux, you can use the echo command and pipe the results into your program. For example:
#my_bash_script.sh
echo "0.2
0.47
" | Program
Perhaps you can do something similar if you are working with Windows batch files. Check out this as one resource:
https://ss64.com/nt/syntax-redirection.html
This is a workaround, not an answer, but it is too long for a comment. After researching this for a while, I don't think Matlab can do what the question requests. (Not without compiling the Matlab code into an executable.) I got around it by writing a function (call it Meta) that reads the entire "batch" file of responses and returns them as a string array. I gave Program two extra input parameters: a flag for interactive/batch running (FlagBatch), and a string for the batch filename (BatchName). If FlagBatch is 1, Program uses Meta to read BatchName and generate ResponseArray, which is used to provide responses to any requests from Program. Kludgey, but it works, with minimal reprogramming of Program. (Of course, I had to have access to Program's code, but if I'd only had an executable from someone else, then I wouldn't have had this problem in the first place!)
Another workaround. Define myinput (see below), and use that everywhere to replace input. As in my other workaround, you give Program two extra input parameters: a flag for interactive/batch running (FlagBatch), and a string for the batch filename (BatchName). Also have
if FlagBatch==1, fid=open(BatchName); end
near top of Program. This approach is nice when you have dozens of input statements scattered all over Program (and various subroutines/functions).
function A=myinput(fileID,prompt,formatSpec,sizeA)
% A=myinput(fileID,prompt,formatSpec);
% Function myinput will read from either stdin (keyboard) or from a file,
% allowing programs' inputs to be entered interactively or from a file.
% Use it instead of Matlab's built-in functions input and fscanf.
% fileID = file ID (fid) of the opened file, or 0 for keyboard input.
% prompt = the prompt string (not used for file input)
% formatSpec = string containing Matlab format spec;
% not used for keyboard input
% sizeA = size of A; basically specifies how many times to use formatSpec;
% not used for keyboard input
%
% Example Uses in Program (where fid would have been set earlier):
% NumOrcs=myinput(fid,'Enter # of orcs','%i',1);
% MapFile=myinput(fid,'Enter filename for LotR map','s',1);
% [Sgimli,Slegolas]=myinput(fid,'Strengths of Gimli and Legolas?','%g',2);
%
if fileID==0
if formatSpec=='%s'
A=input(prompt,'s');
else
A=input(prompt);
end
else
A = fscanf(fileID,formatSpec, sizeA);
end
return

How to continue in a loop when the file does not exist?

This script download many files. However, I want the loop to continue when it doesn't find any file: File mot found.
for ii=1:length(t2)
d=t2(ii);
if year(d)>=2011
download(d)
end
end
Any ideas? Thanks
I'm guessing download is a function that downloads something from a server, so I don't see how exist will work. Either way, you can simply use a try catch block:
for ii=1:length(t2)
d=t2(ii);
if year(d)>=2011
try
download(d)
catch
end
end
end
You could add an 'if' statement before the download(d) statement to ask whether the file exists. Something like:
for ii=1:length(t2)
d=t2(ii);
if year(d)>=2011
if exist(d) % where d is the file
download(d)
else
continue % Jump to next loop iteration if file doesn't exist
end
end
end
Assuming that 'd' is the file in question that you want to download. You might need to use the file's whole address to make sure Matlab can find it.
In addition to the check before downloading you can do try-catch. This download is likely to throw an error if file is missing or something (load does, but I don't have download). You get this error for load:
Error using load
Unable to read file 'lala.m'. No such file or directory.
Now the same with try-catch:
try
load('lala.m')
catch
disp('No such file')
end
It will display No such file, which might not be the real error thrown by load, but you can do multiple catches.
This doesn't have a large advantage when the only thing that can go wrong is "file does not exist", but if you have multiple possible fail points you can have single try-catch (if you don't care what went wrong, just that something did) instead of a long cascade of ifs checking everything.

Matlab: error using fprintf

This is a script written by someone else, and I don't understand why it is giving me this error (I don't really know Matlab, but this appears to be a fairly straightforward script, so I'm a bit stumped).
The file starts with
clear all
filein=['Runs/'];
Namein1=['AIC'];
Nameout=['Nash'];
It then does a bunch of calculations to get Nash-Sutcliffe coefficients (not important for this issue) and then tries to write the results to one file:
%Write Nash
%Output file writing
%Write file header
D={'Conbination','Nash with Error','Nash-error','RMSE','RMSE-error',...
'AIC', 'MinNash', 'MaxNash'};
NameOut=[filein,Nameout, '.txt'];
fileID = fopen(NameOut,'w');
for i=1:length(D)-1
fprintf(fileID,'%s\t',D{i});
Then more stuff follows, but this is where I get the error message:
Error using fprintf
Invalid file identifier. Use fopen to generate a valid file identifier.
Error in Nash_0EV_onlyT (line 169)
fprintf(fileID,'%s\t',D{i});
I don't get what is wrong here? The script specifies the file, and uses fopen...? Isn't it supposed to create the file Nash.txt with the fopen statement (this file currently does not exist in my folder Runs/)? What am I missing? Thanks!
PS I am running Matlab2013a (group license via the university) on a MacBook Pro with OSX 10.8
Try using fclose all before calling this script again. Often when testing, the file handle is never released (an error occurs before the file is closed), causing fopen on the same file to fail.
The better way to do this would be to use a more fail-safe construct:
NameOut = [filein Nameout '.txt'];
fileID = fopen(NameOut,'w');
if fileID > 0
try
for i = 1:length(D)-1
fprintf(fileID,'%s\t',D{i});
end
fclose(fileId);
catch ME
fclose(fileId);
throw(ME);
end
else
error('Error opening file.');
end
I am running Win 10 and matlab 2015a, but it happens in mine too.
finally, I realise that the matlab.exe can't write file in the folder /../bin/
so, change to
Nameout=['C:\Users\yourname\DesktopNash'];
try it, then tell me what' going on.
Okay, so as I said, I don't know Matlab... I hadn't properly specified the path for writing! So it was reading the input but I guess didn't know where to write to. Thanks for the answers, it did help me narrow down the problem!

Can't close text file because MATLAB uses it after failed execution

I call a function (containing fopen and fclose) from the Command Window and then after MATLAB encounters an error that I fix (the runtime of the program stops after I save my corrections), I want to delete the file it created, in order to repeat the process. However, MATLAB, somehow, still has the file open and typing in fclose(f), in the Command Window does not make MATLAB let go of the file.
function something(something)
f = fopen('something.txt', 'w');
%statments with fprintf
fclose(f);
end
You may not have access to the handle f from outside the function, in which case you can try fclose('all') from the Matlab command window.
Generally it is best practice to use a try .. catch ... statement around code that uses a file, so that you always call fclose and release the handle if an error occurs.
If you are still unable to delete the file, and assuming it is not locked by another process (for example if you are viewing it externally in Windows Notepad), it may be that you are calling library functions from Matlab and that the shared library maintains the file lock. In this case, try reloading the library using the unloadlibrary and loadlibrary commands.
Using an onCleanup object can be very useful in this case.
Here's your code rewritten to use onCleanup - the fclose will now get called when the function terminates whether normally, or because of an error.
function something(something)
f = fopen('something.txt', 'w');
closer = onCleanup( #()fclose(f) );
% statements with fprintf
end
The documentation also includes an example for exactly this case.