Here is my proposal for tagging messages with (the value of) an arbitrary expression at the time of message generation. The tag is placed inside the the message itself.
ClearAll[withTaggedMsg]
SetAttributes[withTaggedMsg, HoldAll]
withTaggedMsg[exp_, label_: "When"] := Function[,
Internal`InheritedBlock[{MessagePacket},
Unprotect @ MessagePacket;
mp : MessagePacket[__, _BoxData] /; !TrueQ[$tagMsg] :=
Block[{$tagMsg = True},
Style[Row[{label, HoldForm[exp], "=", exp, " "}, " "], "SBO"] /. tag_ :>
MapAt[RowBox[{ToBoxes @ tag, #}] &, mp, {-1, 1}] // Identity
];
#
],
HoldAll]
Usage:
Do[i^0, {i, -1, 1}] // withTaggedMsg[i]

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

Note: this only works with variables that are either globally accessible or are scoped using Block. For example,
f[x_] := Message[f::brains, x]
f[5] // withTaggedMsg[x]
(* At iteration x = x f::brains: -- Message text not found -- (5) *)
Module[{x = 5},
Message[f::brains, x]
] // withTaggedMsg[x]
(* At iteration x = x f::brains: -- Message text not found -- (5) *)
With[{x = 5},
Message[f::brains, x]
] // withTaggedMsg[x]
(* At iteration x = x f::brains: -- Message text not found -- (5) *)
Block[{x = 5},
Message[f::brains, x]
] // withTaggedMsg[x]
(* At iteration x = 5 f::brains: -- Message text not found -- (5) *)
This means that any variable that is scoped using Block can be used to tag a message. So, loop variables from Do and Table are accessible via this method, in addition to any Block variable. This makes it indispensable as a debugging tool.
Do[i^0, {i, -1, 1}]the iteration is viaMap, eg(1/#) & /@ Range[-10, 10]. How to preserve message tagging w/o the named iterator? – alancalvitti Dec 20 '12 at 22:22Block[{i = #}, (1/#)] & /@ Range[-10, 10] // withTaggedMsg[i]. You could possibly useCheck, e.g.Check[1/#, Print["...happened with argument: ", #]] & /@ Range[-10, 10];(It may be possible collapse the printed line and the message into one.) It seems to me thatDois always going to be cleaner. – Mr.Wizard Dec 21 '12 at 01:05