3
$\begingroup$

If we run this code:

FindCycle[1, 2, 3, 4, 5]

It will give a error information like:

How to get the error info promption of FindCycle::argb: FindCycle called with 5 arguments; between 1 and 3 arguments are expected.


As the comments,the method of Kuba's FindCycle::argb /. Messages[FindCycle] will get a string template with ` `.The same case of rcollyer's method.But actually I want get a string(..between 1 and 3 arguments..) but not a string template(..between `3` and `4` arguments..).

$\endgroup$
  • $\begingroup$ @Kuba ok. I was wrong. Here's the duplicate ... which I wrote. :P $\endgroup$ – rcollyer Feb 26 '17 at 16:57
  • 2
    $\begingroup$ @Kuba here it is Internal`HandlerBlock[{"MessageTextFilter", Print[{##}] &}, FindCycle[1, 2, 3, 4, 5]]. The first argument to "MessageTextFilter" gives the text. $\endgroup$ – rcollyer Feb 26 '17 at 17:00
  • 1
    $\begingroup$ This seems to me like a duplicate of mathematica.stackexchange.com/q/20367/121 $\endgroup$ – Mr.Wizard Feb 26 '17 at 20:15
  • 3
    $\begingroup$ @rhermans I appreciate your idea to move all external images to imgur SE. May be it is better to introduce a delay into your script, so that SE users, question authors and the front page do not get overwhelmed by updates. Such updates can be done in the same way like Community user bumps random questions once an hour. $\endgroup$ – Shadowray May 12 '17 at 15:51
  • 2
    $\begingroup$ @rhermans,yode I think this update is really good thing to do. I just suggest to update one question per hour (or so). $\endgroup$ – Shadowray May 12 '17 at 16:04
10
$\begingroup$

Something different:

Attributes[getMsgString] = HoldFirst;

getMsgString[x_] := 
 Block[{MessagePacket =Return[ToString@ToExpression[#3[[1, 1, 3]]], Block] &}, x]

Now:

FindCycle[1, 2, 3, 4, 5] // getMsgString
"FindCycle called with 5 arguments; between 1 and 3 arguments are expected. >>"

To address the case raised the comments here is one approach:

flatFraction = 
  StringReplace[#, 
    Shortest["\\!\\(" ~~ n__ ~~ "\\/" ~~ d__ ~~ "\\)"] :> n ~~ "/" ~~ d] &;

getMsgString[x_] := 
  Block[{MessagePacket =
    Return[#3[[1, 1, 3]] // flatFraction // ToExpression // ToString, Block] &}, x]

500 / 0 // getMsgString
Infinite expression 1/0 encountered. >>

Incidentally I copied the string above using Plain Text. The direct output is:

"Infinite expression \[NoBreak]1/0\[NoBreak] encountered. \[RightSkeleton]"

If that is a problem additional processing can be applied; let me know if you need help with that.


Edit for more general case

Attributes[getMsgString] = HoldFirst;

getMsgString[x_] := 
 Block[{MessagePacket = 
    Return[First[
       FrontEndExecute[
        FrontEnd`ExportPacket[
         First[MathLink`CallFrontEnd[
           FrontEnd`UndocumentedTestFEParserPacket[
            ToExpression[#3[[1, 1, 3]]], False]]], "PlainText"]]], 
      Block] &}, x]

Examples

enter image description here


More MessagePacket shenanigans:

$\endgroup$
  • $\begingroup$ I read all posts you linked,but I have to say your solution better than all of it.Just a preference for me.Your result not a normal string.If you can update a little,I will change the accepted. $\endgroup$ – yode Feb 27 '17 at 7:24
  • $\begingroup$ I have given a little change in your code for concise,if you mind that,you can rollback it.Actually make "Infinite expression \!\(\*FractionBox[\"1\", \"0\"]\) encountered." into "Infinite expression ∞ encountered.".It's seem not easy to do. $\endgroup$ – yode Feb 27 '17 at 7:38
  • $\begingroup$ @yode That is certainly possible on a case-by-case replacement but I suspect you mean more generally than that? I'll edit my answer with one possible method. $\endgroup$ – Mr.Wizard Feb 27 '17 at 13:17
  • $\begingroup$ @yode you should already know how to deal with string representation of expression inside strings: mathematica.stackexchange.com/a/138544/5478 $\endgroup$ – Kuba Feb 28 '17 at 8:33
  • $\begingroup$ @Kuba Funny,actually I have tried that method yesterday,it's not work.But I give another try just now.It work out.And have a update by your this code. $\endgroup$ – yode Feb 28 '17 at 9:26
5
$\begingroup$

The code below makes me think I have missed something obvious:

Quiet @Cases[
    Internal`HandlerBlock[
       {"Message", Sow}
     , Reap @ FindCycle[1, 2, 3, 4, 5]
   ]
 , HoldPattern[Message[mn : MessageName[head_, name_], params___]] :> 
      StringTemplate[mn /. Messages[head]][params]
 , ∞
]
{"FindCycle called with 5 arguments; between 1 and 3 arguments are \
 expected."}
$\endgroup$
  • $\begingroup$ We can use Quiet[Internal`HandlerBlock[...]] to get same result.But I have to say I cannot totally understand your mma syntax here. :) $\endgroup$ – yode Feb 26 '17 at 18:57
  • $\begingroup$ @yode I'm not sure what do you mean. Your short code returns: {FindCycle[1,2,3,4,5],{{Hold[Message[FindCycle::argb,FindCycle,5,1,3],False]}}} for me. $\endgroup$ – Kuba Feb 26 '17 at 18:59
  • $\begingroup$ I mean this. $\endgroup$ – yode Feb 26 '17 at 19:01
  • $\begingroup$ @yode Ok, now I understand, I though you meant I can use Quiet to make the code shorter :) $\endgroup$ – Kuba Feb 26 '17 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.