How to implement try/catch/end try in Mathematica in the most simple way?

You could do

f[x_, y_] := Check[x/y, $Failed]

f[1, 0]

During evaluation of Power::infy: Infinite expression 1/0 encountered.

$Failed

In this way you can pass the $Failed to the caller and react to it, instead of passing the default of ComplexInfinity (which is useful in its own way).


Maybe something like this?

f[x_, y_] := Module[{}, Quiet@Check[x/y, Throw["I give up, bad input"]]];

f[1, 0]
(* Throw::nocatch : Uncaught Throw[I give up, bad input] returned to top level. *)

Here's a simple way to do that. First define something to validate your output and which will Throw a tag if invalid. Then Catch that:

validateResp // Clear
validateResp[resp_, validator_, error_: Automatic] :=
  If[! TrueQ[validator@resp],
   Throw[resp, Replace[error, Automatic :> $tryCatchTag]],
   resp
   ];
tryCatch // Clear
SetAttributes[tryCatch, HoldFirst];
tryCatch[
  expr_,
  error : _String | Verbatim[Blank][] : "BadValue",
  handler : Except[_String | Verbatim[Blank][]] : (#2 &),
  validator : Except[_String | Verbatim[Blank][]] : (Length[$MessageList] == 0 &)
  ] :=
 Block[{$tryCatchTag = error},
  Catch[
   validateResp[expr, validator, error],
   error,
   handler
   ]
  ]

You'd use it like this:

tryCatch[
 1/0
 ]

(* Message: Power::infy: Infinite expression 1/0 encountered. *)

(* Out: "BadValue" *)

Unfortunately there's no global sense of "if an error occurred" so by default my validator just checks if any messages were generated when evaluating, but this can be anything. You can also put a deeper validateResp in there if you want. You can also easily throw your own errors and catch anything like:

tryCatch[
 If[! TrueQ[n > 2],
   validateResp[False, False &, "BadN"],
  1/0
  ],
 _
 ]

"BadN"

Which if the first test passed would give you

tryCatch[
 If[False,
   validateResp[False, False &, "BadN"],
  1/0
  ],
 _
 ]

(* Message: Power::infy: Infinite expression 1/0 encountered. *)

(* Out: _ *)