Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting up diagnostic error messages in large Mathematica projects

Whenever I create a large Mathematica project I run into this problem: Preventing avalanche of runtime errors in Mathematica, i.e., Mathematica's error message are opaque, archaic, and legion.

The idea then is to disable all of Mathematica's own error messages and implement type checking and error messages of your own in every Function and Module. However I have not found a simple and efficient way of doing this and end up with, e.g., some function generating an error 20 function calls deep and then get a whole cascade of error messages all the way back up to the main routine.

How would you set up a simple mechanism for this that only generates one error message at the function that experiences the error and a simple list of the chain of function calls?

EDIT: Since it has come up in a couple of answers; I am specifically looking for something lightweight regarding the output it produces (otherwise I could just stick with Mathematica's error messages) and obviously also lightweight in computational overhead. So while Stack and Trace are definitely light on the overhead, their output in complex projects is not quick to parse and some work needs to be done simplifying it.

like image 703
Timo Avatar asked Nov 14 '10 07:11

Timo


2 Answers

One attempt to implement @Timo's idea (theStack)

Incomplete and perhaps flawed, but just to keep thinking about it:

Clear["Global`*"];
funcDef = t_[args___]  \[CircleMinus] a_ :>
   {t["nude", args] := a,
    ReleaseHold[Hold[t[args] :=
       (If[! ValueQ[theStack], theStack = {}];
        AppendTo[theStack, ToString[t]];
        Check[ss = a, Print[{"-TheStack->", Evaluate@theStack}]; 
         Print@Hold[a]; Abort[]];
        theStack = Most@theStack;
        Return[ss])
      ]]};
v[x_, y_]\[CircleMinus]  (Sin@ g[x, y]) /. funcDef;
g[x_, y_]\[CircleMinus]  x/y /. funcDef;
v[2, 3]
v[2, 0]

Output:

Out[299]= Sin[2/3]

During evaluation of In[295]:= Power::infy: Infinite expression 1/0 encountered. >>

During evaluation of In[295]:= {-TheStack->,{v,g}}

During evaluation of In[295]:= Hold[2/0]

Out[300]= $Aborted
like image 108
Dr. belisarius Avatar answered Oct 19 '22 23:10

Dr. belisarius


To get the ball rolling here is one idea that I've been toying with; the creation of a pseudo stack.

First make a global variable theStack={} and then in every Function or Module start with AppendTo[theStack,"thisFuncName"] and end with theStack=Most@theStack. Assuming moderate (~a few tens) depth of function calls, this should not add any significant overhead.

Then implement your own typing/error checking and use Print@theStack;Abort[]; on errors.

Refinements of this method could include:

  1. Figuring out a way to dynamically get "thisFuncionName" so that the AppendTo[] can be made into an identical function call for all Functions and Module.
  2. Using Message[] Instead of Print[].
  3. Pushing other important variables / stateful information on theStack.
like image 27
Timo Avatar answered Oct 19 '22 22:10

Timo