Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell Mathematica to quit upon a debug-error

Is there a setting (I'd expect it to be an environment variable) in Mathematica that would make the kernel quit at the occurrence of a debug error? Often, I'll get debug errors and the notebook will continue evaluating bad data forcing me to restart the kernel.

like image 913
rjkaplan Avatar asked Nov 02 '11 20:11

rjkaplan


People also ask

How do I close a debug window?

Press SHIFT+F5. Click the Stop debugging (Shift+F5) button ( )

How do you debug in Mathematica?

To start a debugging session, you would typically launch Mathematica in a debug mode and ensure that all the files that you wanted to work with were loaded. More details are found in the launching section. However, a quick summary is to select a . nb file, right-click, and choose Debug As > Mathematica, as shown below.


2 Answers

Following an idea borrowed from the Mathematica toolbag:

myMessage::debug = "Something went horribly wrong";

Unprotect[Message];
Message[mm : myMessage::debug] :=
 Block[{$inMsg = True, result},
   Message[mm];
   Quit[]] /; ! TrueQ[$inMsg]
Protect[Message];

Here, replace myMessage::debug with the actual message type you want to intercept.

Normal message:

Message[Power::infy]

(* ===> 
        StringForm::sfr: Item 1 requested in "Infinite expression `1` 
        encountered. >>" out of range; 0 items available. >> 

        Power::infy: Infinite expression `1` encountered. >> 
*)

Your 'debug' message:

Message[myMessage::debug]

(* ===>
myMessage::debug: Something went horribly wrong

 [kernel quits...]
*)

Update

Assert messages get some additional arguments, so you have to catch those too. And, by the way, you have to put the actual message name in the definition (not using the example message I used above):

Unprotect[Message];
Message[mm : Assert::asrtfl, m___] :=
 Block[{$inMsg = True, result},
   Message[mm, m];
   Quit[]] /; ! TrueQ[$inMsg]
Protect[Message];
like image 78
Sjoerd C. de Vries Avatar answered Nov 09 '22 19:11

Sjoerd C. de Vries


This response assumes that by "debug error" you mean that a Message has been issued. For example, a message is issued as a warning if one attempts to divide by zero:

In[1]:= Print[1/0]

        Power::infy: Infinite expression 1/0 encountered. >>

        ComplexInfinity

Note how ComplexInfinity was printed by the Print statement even though the warning message was issued, showing that the computation continues after the "error".

I will not re-iterate @Sjoerd's excellent answer which shows how to configure a Mathematica session so that the kernel will exit if any message is issued by any evaluation. If you wish to be more selective and only quit the kernel if a particular evaluation issues a message, then the following function might be useful:

ClearAll[checkQuit]
SetAttributes[checkQuit, HoldFirst]
checkQuit[expr_, HoldPattern[messages_:Sequence[]]] :=
  Check[expr, Message[checkQuit::quit]; Quit[], messages]
checkQuit::quit = "The kernel is being shut down!";

With this definition in place, you can force the kernel to quit after any message is issued by a particular evaluation:

In[37]:= checkQuit[Print[1/0]]

         Power::infy: Infinite expression 1/0 encountered. >>
         checkQuit::quit: The kernel is being shut down!

If might be convenient to only quit the kernel if certain messages are issued. To this end, checkQuit accepts an optional second argument that can be used to specify the messages of interest:

In[6]:= checkQuit[{}[[10]], Power::infy]

        Part::partw: Part 10 of {} does not exist. >>
Out[6]= {}[[10]]

Note how the kernel was not exited since the message did not match Power::infy. But consider:

In[7]:= checkQuit[1/0, Power::infy]

        Power::infy: Infinite expression 1/0 encountered. >>
        checkQuit::quit: The kernel is being shut down!

Here the kernel quits because the indicated message appeared. It is possible to filter multiple messages or even pre-defined groups of messages -- see Check for details.

like image 41
WReach Avatar answered Nov 09 '22 17:11

WReach