TransWikia.com

How to catch complete error message information, including the message text as it would be printed?

Mathematica Asked on June 12, 2021

If I evaluate this expression:

Module[{}, 1/0;0^0]; msg = $MessageList

I get:

"Power::infy: Infinite expression 1/0 encountered. >>"
"Power::indet: Indeterminate expression 0^0 encountered. >>"
{Power::infy,mrtError::function}

How can I collect the complete error messages in msg, instead of just the first part?
Something for msg like:

{"Power::infy: Infinite expression 1/0 encountered. >>"
,"Power::indet: Indeterminate expression 0^0 encountered. >>"}

Some clue?

5 Answers

Update See here for a documented way to do the very same thing in v10.0 or later.


This method will only catch those messages which would actually get printed, not those which are Quieted or turned Off.

We can use handlers:

messages = {}
clearMessages[] := messages = {}
collectMessages[m_] := AppendTo[messages, m]
Internal`AddHandler["Message", collectMessages]

Then do

clearMessages[]
1/0; 0/0;
messages

Mathematica graphics

Internal`RemoveHandler["Message", collectMessages]

Reference and details: How to abort on any message generated?

Correct answer by Szabolcs on June 12, 2021

You can use Messages[foo] to get the text of any message. With that, we can proceed as follows to extract the text of the messages that were last generated:

Module[{}, 1/0;0^0]; msg = $MessageList; (* last errors *)

With[{messages = ReleaseHold@
    DeleteDuplicates[# /. HoldPattern@MessageName[s_, _] :> Messages@s] &},

    # /. messages@#] &@msg
(* {{Infinite expression `1` encountered.,Indeterminate expression `1` encountered.}} *)

Note that you will not be able to retrieve whatever was inserted in the placeholder `1` with this.

Answered by rm -rf on June 12, 2021

Simply you could use $MessagePrePrint to get the "fillers" and $MessageList as you did to get the message name they belong to:

$MessagePrePrint = Sow;

Reap[
 Module[{}, 1/0; 0^0]; $MessageList
]
{{Power::infy,Power::indet},{{1/0,0^0}}}

For complete control you could go low-level and intercept MessagePacket as I did for:
Prepend Information to Warning Messages

Answered by Mr.Wizard on June 12, 2021

The following method will capture all messages, regardless of whether they are Quieted or turned Off. Messages that are turned off will be wrapped in $Off.

You could always capture the information directly,

myMessageList = {};
Internal`InheritedBlock[{Message, $InMsg = False},
 Unprotect[Message];
 Message[msg_, vars___] /; ! $InMsg :=
  Block[{$InMsg = True},
   AppendTo[myMessageList, {HoldForm[msg], vars}];
   Message[msg, vars]
   ];
 (* code to run *)
 Module[{}, 1/0; 0^0]
 ];
myMessageList

(* {{Power::infy, HoldForm[1/0]}, {Power::indet, HoldForm[0^0]}} *)

Answered by rcollyer on June 12, 2021

In version 10 or later, we can use EvaluationData.

EvaluationData[1/0; 0^0]

Mathematica graphics

Behind the scenes, this uses handlers, like in my first answer, meaning that only those messages will be recorded which would get printed.

Answered by Szabolcs on June 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP