How do you provide custom error message for Ecto's cast errors?

If you provide a string to an :integer field you get
errors: [count: {"is invalid", [type: :integer, validation: :cast]}]
in a changeset, which is not helpful for a user. Unfortunately Ecto.Schema.field/3 doesn’t accept custom error messages (as of v3.9 at least).

I want to return something like “should be a number” to a user instead of “is invalid”.

One solution could be a create a custom integer type, which can return a custom error message. Another way could be processing this in web layer in some kind of humanize_error function, replacing default “is invalid” with “should be a number”.

For now I’ve settled with custom ecto types, but as their number started to grow, I want to re-evaluate my approach. So I wonder how do others solve similar issues? I would appreciate your thoughts.

PS. What I like about custom types, is that I can also use them to clean up values before casting them. I can trim strings, remove double spaces, drop “.0” and “,0” from integers.

Have you tried using gettext for this? You should have some examples in a generated phoenix project.

The metadata in the error would allow you to do the transformation you mention to the error in Ecto.Changeset.traverse_errors (which is likely already called somewhere in your codebase). You can ignore the existing error string and match on metadata[:validation] + metadata[:type].

1 Like