Geo.*.cast functions crash instead of returning :error
narrowtux opened this issue · comments
Example:
Geo.Point.cast(%{"type" => "Pint", "coordinates" => [0, 1]})
crashes with
** (FunctionClauseError) no function clause matching in Geo.JSON.do_decode/3
The following arguments were given to Geo.JSON.do_decode/3:
# 1
"Pint"
# 2
[0, 1]
# 3
nil
Attempted function clauses (showing 6 out of 6):
defp do_decode("Point", [x, y], crs)
defp do_decode("LineString", coordinates, crs)
defp do_decode("Polygon", coordinates, crs)
defp do_decode("MultiPoint", coordinates, crs)
defp do_decode("MultiLineString", coordinates, crs)
defp do_decode("MultiPolygon", coordinates, crs)
lib/geo/geo_json.ex:65: Geo.JSON.do_decode/3
lib/geo/point.ex:24: Geo.Point.cast/1
Instead, they should just return :error
.
Also I noticed that it will even decode JSON first, however it still uses the decode function with a bang instead of catching the error. I know this is a bit more to code, but goes a long way because one can then return meaningful errors in APIs when the user supplies invalid JSON or GeoJSON.
cast
must follow whatever contract Ecto.Type has so there is a bug there. I'm not sure if changes should happen at Geo.JSON without causing a breaking change. If it's throwing an error now, it might make sense for it to continue to, but maybe a better kind of error.
The contract of Ecto.Type is to return :error
when you can't cast the values properly. Sadly you can't add more information as to why you can't cast them, which would be useful for more complex types such as all the Geo types.
However, I can't see myself using try
every time I create a changeset for data with Geo types in it.
Resolved in 2.1.0