-
Notifications
You must be signed in to change notification settings - Fork 0
Symbols Guide
MFailureQ /@ {
$Failed, $Aborted, $Canceled, Failure["any","Message"->"Generic message"]
}
{True,True,True,True}
Basic usage:
MGenerateAll[General::argt,foo,2,3,4]General::argt: foo called with 2 arguments; 3 or 4 arguments are expected.
Failure["argt", <| "MessageTemplate" :> General::argt, "MessageParameters" -> {foo, 2, 3, 4} |> ]
Use custom tags for a more fine grained control flow:
MCatch @ MThrow["custom tag",General::argt,foo,2,3,4]
Failure["custom tag", <|"MessageTemplate" :> General::argt, "MessageParameters" -> {foo, 2, 3, 4}|>]
Association/Failure oriented syntax:
MCatch @ MThrow[foo::argx, <|"arg"->bar|>]
Failure["argx", <|"MessageTemplate" :> foo::argx, "MessageParameters" -> <|"arg" -> bar|>|>]
Adding payload can be invaluable for complex flow:
MCatch @ MThrow[
"custom tag"
, General::argt
, foo,2,3,4
, <|"Payload"->"additional information"|>
]
Failure[ "custom tag" , <|"MessageTemplate" :> General::argt , "MessageParameters" -> {foo, 2, 3, 4} , "Payload" -> "additional information" |> ]
More idiomatic approach to If[Test @ expr, exception @ expr, expr]:
MCatch[
$Aborted // MHandleResult[]; 1
]
Failure["err", <|"Message" -> "$Aborted"|>]
MCatch[
NotAString[] // MHandleResult[
Except[_String] , Function[res, MThrow[foo::string, Head[res], _String]]
]
]
Failure["string", <|"MessageTemplate" :> foo::string, "MessageParameters" -> {NotAString, _String}|> ]
More idiomatic approach to If[ FailureQ[expr], handler @ expr, expr]:
$Failed // MOnFailure[foo]
foo[$Failed]
MCatch[ $Failed // MOnFailure[MThrow] ]
$Failed
There is a shorter version for throwing though:
MCatch[ $Failed // MThrowOnFailure ]
$Failed
I find unevaluated expressions hard to manage with respect to flow control so I would like always to get a Failure:
foo[x_]:=x^2;
foo // MFailByDefault;
foo[1,2]foo::argpatt: There are no rules associated with signature foo[Integer, Integer].
Failure["argpatt", <|"MessageTemplate" :> foo::argpatt, "MessageParameters" -> {"foo[Integer, Integer]"}|>]
The idea behind those utilities originates from https://mathematica.stackexchange.com/q/116571/5478
StructUnmatchedPositions[
<|"a" -> <|"b" -> 2, "c"->3, "d" -> 4|>|>
, KeyValuePattern[{"a" -> KeyValuePattern[{"b" -> _Integer, "c" -> _String, "d" -> _List}]}]
]
{ {Key["a"], Key["c"]} , {Key["a"], Key["d"]} }
MValidate[
<|"a" -> <|"b" -> 2, "c"->3, "d" -> 4|>|>
, KeyValuePattern[{"a" -> KeyValuePattern[{"b" -> _Integer, "c" -> _Integer, "d" -> _Integer}]}]
]
True
ClearAll[foo];
$fooPatt = KeyValuePattern[{"a" -> _Integer}];
foo // MValidateByDefault[ $fooPatt ]
foo[ in: $fooPatt]:= in["a"]
foo @ <|"a" -> 1|>
1
foo @ <|"b" -> 1|>foo::invStruct: foo: Invalid values at positions: {Key[a]} Input needs to match: <|a -> _Integer|>
Failure["400", <| "MessageTemplate" :> MessageName[foo, "invStruct"], "MessageParameters" -> {foo, "\t{Key[a]}", "\t<|a -> _Integer|>"}|>]
Module[{x = 1, y = 2, z = "string"}, ToKeyValue @ {x,y,z}]
{"x" -> 1, "y" -> 2, "z" -> "string"}