# Prepend Information to Warning Messages

I have a function running within a Do loop that sometimes issues a warning. I'd like to prepend the warning with the loop ctr so that I can go back and debug that instance later.
Basically, I would like to modify the following line,

Do[i^0, {i, -1, 1}]


so that instead of displaying the warning:

Power::indet: Indeterminate expression 0^0 encountered. >>


it displays:

i=0, Power::indet: Indeterminate expression 0^0 encountered. >>


Where i==0 is the iteration that i^0 issues the warning.

Thanks

-

rcollyer's method looks great but for a reason I have yet to determine it fails in Mathematica 7. Here is a variation that does not.

Block[{$MessagePrePrint},$MessagePrePrint := Row@{#, " at i = ", i} ~ToString~ StandardForm &;
Do[i^0, {i, -1, 1}]
]


This may not be ideal however, as every field in the message gets this tag. For example, if you enter the spurious Inner[f, {{1, 2}}, {3}] you get:

Inner::incom: Length 2 at i = 1 of dimension 2 at i = 1 in {{1,2}} at i = 1 is incommensurate with length 1 at i = 1 of dimension 1 in {3} at i = 1. >>

Perhaps this is a more flexible and convenient form:

EDIT: Full rewrite to place the tag in the message itself

SetAttributes[withTaggedMsg, HoldAll]

withTaggedMsg[sym_] := Function[,
InternalInheritedBlock[{MessagePacket},
Unprotect[MessagePacket];
MessagePacket[name__, BoxData[obj_, form_]] /; ! TrueQ[$tagMsg] := Block[{$tagMsg = True},
Identity@MessagePacket[name, BoxData[RowBox[{
ToBoxes @ Style[
Row[{"At iteration", HoldForm[sym], "=", sym, Spacer[5]}, " "],
Black],
obj}], form]]
];
#
], HoldAll]


Usage:

Do[i^0, {i, -1, 1}] // withTaggedMsg[i]


-
 Argh, I hadn't thought about what happens to the other fields. I do like your second method better, though; it is more readable and closer to what the OP wants. Although, the two cell output isn't to my liking, all that much, it is very nice, overall. +1 – rcollyer Jul 12 '12 at 0:54 I added a fix per Rojo. – rcollyer Jul 13 '12 at 14:23 @rcollyer thanks! – Mr.Wizard♦ Jul 13 '12 at 15:10 This is why I participate here: I'm having to make use of this to debug some code to load a file, and this allows me to spit out the line numbers with the errors. I'd give you another +1 if I could. – rcollyer Oct 11 '12 at 18:34 @rcollyer Glad to be of help, as always. Thanks for letting me know, I value that a lot more than points. – Mr.Wizard♦ Oct 11 '12 at 19:06

rcollyer has a nice solution. Here's another possibility using Check and printing the list of messages generated at the current evaluation.

Quiet@Block[{$OldMessages = 0}, Do[Check[#^#/# &@Mod[i, 2], Print@StringForm["At i=, ", i,$MessageList[[$OldMessages + 1 ;;]]];$OldMessages = Length@$MessageList;], {i, 0, 5}] ]; (* At i=0, {Power::indet,Power::infy} At i=2, {Power::indet,Power::infy} At i=4, {Power::indet,General::stop,Power::infy,General::stop} *)  Remove the Quiet@ if you want to see the actual messages generated. - I cannot seem to make it do exactly what you want do to how messages are created, but here is a serviceable alternative using $MessagePrePrint. $MessagePrePrint formats the variables specified in the message string, and in your example, the message has the form General::indet = "Indeterminate expression 1 encountered."  where the 1 will be replaced by$0^0$, or whatever else you pass to it. It is that argument that $MessagePrePrint operates on, and we can change it to suit us, as follows

Block[{$MessagePrePrint},$MessagePrePrint := ToString[StandardForm[#]] <> " at i = " <> ToString[i] &;
Do[i^0, {i, -1, 1}]
]


where the output will now read "$0^0\text{ at i} =1$".

-
I voted for this and then removed my vote because on v7 I'm getting: An unknown box name (Set) was sent as the BoxForm for the expression. Check the format rules for the expression. I need to figure out why. – Mr.Wizard Jul 11 '12 at 21:21
It seems that v7 doesn't like the fact that InputForm@ToString@StandardForm@HoldForm[0^0] yields "\!$$\*TagBox[\(0\^0$$, HoldForm]\)". Either the form I show in my answer or ToBoxes[ToString[StandardForm@#] <> " at i = " <> ToString[i]] &` appear to work. – Mr.Wizard Jul 11 '12 at 22:25
I guess now that I've provided a work-around for v7 users here in the comments I can +1, so, +1! :-) – Mr.Wizard Jul 11 '12 at 23:05