diff --git a/src/eon_type.erl b/src/eon_type.erl index aa87317..f5ad50a 100644 --- a/src/eon_type.erl +++ b/src/eon_type.erl @@ -286,7 +286,10 @@ typecheck(#spec{term=Term0, type=Type, p_have=P_have}) -> true -> case Type:extra_validation(Term, P_have) of ok -> Term; - {error, Reason} -> {error, {untypable, Reason}} + %% Since the extra_validation is typically used for checks + %% involving several terms, we return a reason given by + %% the validation code instead of a term name. + {error, Reason} -> {error, {untypable, [{x, Type, x, Reason, []}]}} end; false -> Term diff --git a/src/eon_type_error.erl b/src/eon_type_error.erl index 9343b84..e8ffe5d 100644 --- a/src/eon_type_error.erl +++ b/src/eon_type_error.erl @@ -79,4 +79,10 @@ get_root_cause__list_type__test() -> {error, Rsn} = eon_type:check_term([<<"foo">>, 42], test_strings), ?assertEqual({42, test_string}, get_root_cause(Rsn)). +get_root_cause__extra_validation__test() -> + {error, Rsn} = eon_type:check_term([{<<"foo">>, 17}], test_rec_extra), + ?assertMatch({nope, test_rec_extra}, get_root_cause(Rsn)), + {error, Rsn2} = eon_type:check_term([{<<"foo">>, 117}], test_rec_extra), + ?assertMatch({117, test_prim}, get_root_cause(Rsn2)). + -endif. diff --git a/test/test_rec_extra.erl b/test/test_rec_extra.erl new file mode 100644 index 0000000..c1b6399 --- /dev/null +++ b/test/test_rec_extra.erl @@ -0,0 +1,15 @@ +-module(test_rec_extra). +-behaviour(eon_type_rec). +-include_lib("stdlib2/include/prelude.hrl"). +-export([name/0, parameters/0, decl/2, extra_validation/2]). + +name() -> some_obj. + +parameters() -> []. + +decl(_Obj, _Params) -> + [ <<"foo">>, {test_prim, [min,0, max,100]} + ]. + +extra_validation(_Term, _Params) -> + {error, nope}.