diff --git a/src/bin/expect_tests/contract_tests.ml b/src/bin/expect_tests/contract_tests.ml index 53db85afc..4d2d6b5a9 100644 --- a/src/bin/expect_tests/contract_tests.ml +++ b/src/bin/expect_tests/contract_tests.ml @@ -927,4 +927,8 @@ let%expect_test _ = let%expect_test _ = run_ligo_bad [ "compile-contract" ; contract "bad_type_operator.ligo" ; "main" ] ; - [%expect {| ligo: bad type operator (TO_Map (unit,unit)): |}] ; \ No newline at end of file + [%expect {| ligo: bad type operator (TO_Map (unit,unit)): |}] + +let%expect_test _ = + run_ligo_bad [ "run-function" ; contract "failwith.ligo" ; "failer" ; "1" ] ; + [%expect {| ligo: Execution failed: {"value":"some_string","type":"string"} |}] \ No newline at end of file diff --git a/src/main/run/of_michelson.ml b/src/main/run/of_michelson.ml index ef26bc11a..1a3b58114 100644 --- a/src/main/run/of_michelson.ml +++ b/src/main/run/of_michelson.ml @@ -3,6 +3,21 @@ open Trace open Memory_proto_alpha.Protocol.Script_ir_translator open Memory_proto_alpha.X +module Errors = struct + let unknown_failwith_type () = + let title () = "Execution failed with an unknown failwith type" in + let message () = "only bytes, string or int are printable" in + error title message + + let failwith data_str type_str () = + let title () = "Execution failed" in + let message () = "" in + let data = [ + ("value" , fun () -> Format.asprintf "%s" data_str); + ("type" , fun () -> Format.asprintf "%s" type_str); + ] in + error ~data title message +end type options = Memory_proto_alpha.options type run_res = @@ -121,7 +136,12 @@ let run ?options (exp:Michelson.t) (exp_type:ex_ty) : ex_typed_value result = let%bind expr = run_expression ?options exp exp_type in match expr with | Success res -> ok res - | _ -> simple_fail "Execution terminated with failwith" + | Fail res -> ( match Tezos_micheline.Micheline.root @@ Memory_proto_alpha.strings_of_prims res with + | Int (_ , i) -> fail @@ Errors.failwith (Z.to_string i) "int" () + | String (_ , s) -> fail @@ Errors.failwith s "string" () + | Bytes (_, s) -> fail @@ Errors.failwith (Bytes.to_string s) "bytes" () + | _ -> fail @@ Errors.unknown_failwith_type () ) + let run_failwith ?options (exp:Michelson.t) (exp_type:ex_ty) : run_failwith_res result = let%bind expr = run_expression ?options exp exp_type in @@ -129,7 +149,7 @@ let run_failwith ?options (exp:Michelson.t) (exp_type:ex_ty) : run_failwith_res | Fail res -> ( match Tezos_micheline.Micheline.root @@ Memory_proto_alpha.strings_of_prims res with | Int (_ , i) -> ok (Failwith_int (Z.to_int i)) | String (_ , s) -> ok (Failwith_string s) - | Bytes (_,b) -> ok (Failwith_bytes b) + | Bytes (_, b) -> ok (Failwith_bytes b) | _ -> simple_fail "Unknown failwith type" ) | _ -> simple_fail "An error of execution was expected" diff --git a/src/test/contracts/failwith.ligo b/src/test/contracts/failwith.ligo index 16c93f026..29b757c3e 100644 --- a/src/test/contracts/failwith.ligo +++ b/src/test/contracts/failwith.ligo @@ -31,3 +31,7 @@ function foobar (const i : int) : int is | Zero (n) -> i | Pos (n) -> (failwith ("waaaa") : int) end + +function failer(const p : int) : int is block { + if p = 1 then failwith("some_string") else skip ; +} with p