# How to abort on any message generated?

Mathematica is a bit unusual as a programming language because it never stops on messages, regardless of whether the message is an error, a warning or just an informative message. It simply prints the message and continues with evaluation. This can cause an avalanche of messages and unpredictable behaviour (e.g. memory may get filled up, bringing the machine to a halt with swapping---this is what happened to me)

Is there a way to immediately abort when any message is generated?

Requirements:

1. if a message would be printed, always abort.
2. if no message would be printed, don't abort.
3. do print the first message so I have a hint about what went wrong
4. the mechanism should work with parallel computations and should abort the full evaluation (i.e. main kernel and all parallel kernels)

There are many ways to handle message printing, including On/Off, Quiet, and possibly others (such as setting some system options). The solution should work well with these. I am afraid manually handling all possible situations is too fragile (there's always a chance something got left out).

I found a solution on MathGroup which aborts, but does not print the message.

I suspect there must exist a robust and simple solution because the Debug palette has a "Break on messages" option.

-
Related stackoverflow link: stackoverflow.com/questions/7987162/… –  Murta Nov 30 '14 at 19:23

I found a robust solution described in this MathGroup message by Maxim Rytin:

messageHandler = If[Last[#], Abort[]] &

InternalAddHandler["Message", messageHandler]


This will abort the computation whenever a message would be printed.

It can be turned off using

InternalRemoveHandler["Message", messageHandler]


Alternatively this can be temporarily applied to a piece of code like this:

InternalHandlerBlock[
{"Message", messageHandler},
(* ... code here ... *)
]


The currently set message handlers can be retrieved using

InternalHandlers["Message"]


(InternalHandlers[] will return all existing handlers)

Whenever a message is generated, Hold[message, printed] is passed to all "Message" handler functions where message is the message text and printed is True is the message would be printed, False otherwise.

The debugging palette appears to use the same mechanism to break on messages.

To make it work with parallel evaluations, one can simply register the same handler on all kernels using ParallelEvaluate.

-
Caveat: functions such as Reduce, Refine and Solve can pass messages to handlers which have printed=True but are somehow never printed. These include FindMinimum::fmmp and N::meprec, which I'm guessing are harmless. –  Tobias Hagge Mar 28 '13 at 2:14

Function[i, {i, ParallelEvaluate[i]};, HoldFirst][
Unprotect[Message, Check, Quiet];
Module[{$guardMes = True,$guardChck = True, $guardQuiet = True}, Message[args___ /;$guardMes] := Block[{$guardMes = False}, Message[args]; If[Head[First@{args}] =!=$Off, Abort[]];
];
Quiet[args___ /; $guardQuiet] := Block[{$guardQuiet = False, $guardMes = False}, Quiet[args] ]; Check[args___ /;$guardChck] := Block[{$guardChck = False,$guardMes = False},
Check[args]
];
]
]


EDIT to try to reflect Szabolcs's and Sjoerd's concerns

Function[i, {i, ParallelEvaluate[i]};, HoldFirst][
Module[{$guardMes = True}, OnMessageAbort[] := ( Unprotect[Message]; Message[args___ /;$guardMes && Head[First@{args}] =!= $Off] := Block[{$guardMes = False, flag = False},
InternalInheritedBlock[{$MessagePrePrint},$MessagePrePrint =
With[{fn = $MessagePrePrint}, Function[i, flag = True; fn[i], HoldAll]]; Message[args]; If[flag, Abort[];] ] ]; Protect[Message]); OffMessageAbort[] := ( Unprotect[Message]; Quiet[ Message[args___ /;$guardMes && Head[First@{args}] =!= \$Off] =.];
Protect[Message];
)
];
];
OnMessageAbort[ker_] := ParallelEvaluate[OnMessageAbort[], ker];
OnMessageAbort[All] := (ParallelEvaluate[OnMessageAbort[]];
OnMessageAbort[]);
OffMessageAbort[ker_] := ParallelEvaluate[OffMessageAbort[], ker];
OffMessageAbort[All] := (ParallelEvaluate[OffMessageAbort[]];
OffMessageAbort[]);


You run that once, and it defines (On/Off)MessageAbort[] in all kernels. You can call OnMessageAbort[] to turn it on on the kernel you run that, or OnMessageAbort[kernel] from the main kernel to turn it on on a particular kernel, just like the second argument to ParallelEvaluate. OnMessageAbort[All] turns it on in all of them. Same goes for OffMessageAbort

-
I just used ParallelEvaluate instead of DistributeDefinitions, and now it works fine in parallel too. I have some ideas why DistributeDefinitions doesn't work here, but the workaround is good enough for now. Please also see groups.google.com/d/msg/comp.soft-sys.math.mathematica/… –  Szabolcs Feb 8 '12 at 18:53
Edited with ParallelEvaluate and as you said it works. Thanks for the link –  Rojo Feb 8 '12 at 18:56
@Szabolcs, reading your question on your link, when you do x=1;ParallelEvaluate[x], it returns {1,1} because your main kernel evaluates the result {x,x} returned from the parallel kernels, not because x was automatically synched –  Rojo Feb 8 '12 at 19:16
Thanks for pointing this out, you are right, ParallelEvaluate does not auto-sync (ParallelEvaluate@Hold@Evaluate[x] can be used for testing). But Parallelize does auto-distribute definitions, so my original problem that I asked about was valid :-) –  Szabolcs Feb 8 '12 at 19:24
+1, good stuff! My version does not yet quite work for parallel, and your does. Nice! –  Leonid Shifrin Feb 8 '12 at 19:37

The easiest and, so far, the best solution I have found is the following:

(* Put the following two lines at the top of every notebook. *)
messageHandler = If[Last[#], Interrupt[]] & ;
InternalAddHandler["Message", messageHandler];


The above code is slightly modified from Szabolcs's solution at the beginning of this thread. I changed Abort to Interrupt. The latter seems to work immediately, while it appears that Abort may be waiting for some portion of the evaluation to finish before stopping everything.

-
Thank you verbeia! As you correctly surmised, I could not figure out how to get the code to look right. –  Ralph Dratman Aug 10 '12 at 11:46

There were some attempts on that in this discussion. I also have this functionality in my debug function posted here

-
Which one do you recommend for practical use? It should work in an environment with no front end, and I need to generalize it for parallel evaluation. –  Szabolcs Feb 8 '12 at 18:27
@Szabolcs I did not use ot for parallel, but I was debugging serious staff with debug, like stack traces with depth 30 or 50, digging deep into internal stuff, and it all worked quite well. So, I'd rather extend debug for parallel, because it serves me very well. It also is useful in that it gives you the (sort of a) stack trace. –  Leonid Shifrin Feb 8 '12 at 18:30
@belisarius's idea works quite well, I'll take a detailed look at debug (for the future) after I've debugged this thing... –  Szabolcs Feb 8 '12 at 18:34
Your debug function looks very useful. There's one big problem though: it breaks on Quieted messages as well. My code, as well as at least some package functions, uses Quiet` at certain positions. –  Szabolcs Feb 8 '12 at 18:41
@Szabolcs I will look into it –  Leonid Shifrin Feb 8 '12 at 18:49

The following works pretty well, at least in Mathematica 10:

1. On the menu bar, go to Evaluation/Debugger Controls/Show Debugger Tools Window.
2. On the window that pops up, check the box to "Break at Messages"

It will then stop and display a green box around the code that is outputting an error message.

-
Actually I was aware of this when asking the question (see the very last paragraph), but I needed a way that doesn't require the front end. It turns out that the method used in the accepted solution is the same the debugger uses. It's good to point out this possibility explicitly though, so +1. –  Szabolcs Oct 30 '14 at 18:01