5
$\begingroup$

Check[expr,failexpr,checkedMessages] will evaluate expr and if it encounters any of the messages in checkedMessages it will evaluate failexpr and return that instead.

But how can I Check for all messages except let's say one?

Quiet has the syntax Quiet[expr,All,notQuiet] that will suppress all messages except those in notQuiet, but Check does not have this option.

A workaround is to use Quiet inside Check:

Check[Quiet[expr,ignoredMessages],failexpr,checkedMessages]

which will trigger for any message that is contained in checkedMessages but not in ignoredMessages. However this has the unintended side effect of also (obviously) Quieting the ignoredMessages.

So for instance the desired function

myCheck[expr_,failexpr_,checkedMessages_,ignoredMessages_]:=..?

should do this:

myCheck[1/0,1,All,{}]
(* show message Power::infy *)
(* return 1 *)

but

myCheck[1/0,1,All,{Power::infy}]
(* show message Power::infy *)
(* return ComplexInfinity *)

(This is a more succinct question about one of the issues in this question)

$\endgroup$
6
  • 2
    $\begingroup$ I'm pretty sure Check[] does not abort an evaluation but let's it run its course; then it failexpr is evaluated. Catch@Check[Check[res = expr, Throw@res, ignoredMessages], failexpr, messages] might work for you. (It's probably better to use Throw and Catch with tags.) $\endgroup$
    – Michael E2
    Nov 6, 2018 at 11:34
  • $\begingroup$ @Kuba Sorry you and Michael are right of course that Check doesn't abort the evaluation, that was sloppy. I don't need it to though, I've added two examples. $\endgroup$
    – Jansen
    Nov 6, 2018 at 13:06
  • $\begingroup$ @MichaelE2 Sorry I shouldn't have written that Check aborts the evaluation, it doesn't and I don't need it to. I want the functionality of Check but just with the addition that it can check for all messages except some specified list. Writing your suggestion as myCheck[expr_, failexpr_, checkedMessages_,ignoredMessages_]:= Block[{res}, Catch@Check[Check[res =expr, Throw@res, ignoredMessages], failexpr,checkedMessages]] gives an error in my examples regarding All. This can be solved by replacing checkedMessages by Evaluate[checkedMessages/.All->Sequence[]]... $\endgroup$
    – Jansen
    Nov 6, 2018 at 13:21
  • $\begingroup$ @MichaelE2 ..and similar for ignoredMessages, but then it returns ComplexInfinity in both examples above. $\endgroup$
    – Jansen
    Nov 6, 2018 at 13:21
  • $\begingroup$ The problem with my proposal is that when multiple messages are emitted, some to be ignored and some not, they are all ignored. I suppose the desired behavior if any checkedMessages are emitted is to return failexpr, yes? $\endgroup$
    – Michael E2
    Nov 6, 2018 at 13:57

1 Answer 1

2
$\begingroup$

Method 1

ClearAll[myCheck];
SetAttributes[myCheck, HoldAll];
myCheck[expr_, failexpr_, checkedMessages_List, 
   ignoredMessages_List] := Module[{res, c, i},
   c = Alternatives @@ HoldForm /@ Unevaluated@checkedMessages /. 
     All -> _;
   i = Alternatives @@ HoldForm /@ Unevaluated@ignoredMessages /. 
     All -> _;
   Check[res = expr, 
    If[AnyTrue[$MessageList, MatchQ[#, Except[i, c]] &], failexpr, 
     res]]
   ];
myCheck[expr_, failexpr_, checkedMessages_, ignoredMessages_List] := 
  myCheck[expr, failexpr, {checkedMessages}, ignoredMessages];
myCheck[expr_, failexpr_, checkedMessages_, ignoredMessages_] := 
  myCheck[expr, failexpr, checkedMessages, {ignoredMessages}];

myCheck[0/0, "Oops!", All, Power::infy]

Examples:

Power::infy: Infinite expression 1/0 encountered.

Infinity::indet: Indeterminate expression 0 ComplexInfinity encountered.

(* Out[]= "Oops!" *)
myCheck[0/0, "Oops!", All, {Power::infy, Infinity::indet}]
Power::infy: Infinite expression 1/0 encountered.

Infinity::indet: Indeterminate expression 0 ComplexInfinity encountered.

(* Out[]= Indeterminate *)

Method 2

I might prefer a pattern-oriented check.

ClearAll[myCheck2];
SetAttributes[myCheck2, HoldAll];
myCheck2[expr_, failexpr_, msgPat_] := Module[{res, failPat},
   failPat = 
    Hold[msgPat] /. {hm : HoldForm[_MessageName] :> hm, 
       m_MessageName :> HoldForm[m]} // ReleaseHold;
   Check[res = expr, 
    If[AnyTrue[$MessageList, MatchQ[#, failPat] &], failexpr, res]]
   ];

Examples:

myCheck2[0/0, "Oops!", Except[Power::infy]]
Power::infy: Infinite expression 1/0 encountered.

Infinity::indet: Indeterminate expression 0 ComplexInfinity encountered.

(* Out[]= "Oops!" *)
myCheck2[0/0, "Oops!", Except[Power::infy | Infinity::indet]]
Power::infy: Infinite expression 1/0 encountered.

Infinity::indet: Indeterminate expression 0 ComplexInfinity encountered.

(* Out[] = Indeterminate *)
myCheck2[Sin[x, y], "Oops!", Except[_::"argx"]]
Sin::argx: Sin called with 2 arguments; 1 argument is expected.

(* Out[]= Sin[x, y] *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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