Skip to content

Commit

Permalink
feat: return :no_route error from ORS (#2524)
Browse files Browse the repository at this point in the history
* fix: return 404 error's from ORS client

* feat: return error to the frontend
  • Loading branch information
firestack authored Mar 29, 2024
1 parent 62ca2f3 commit 80e31cf
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 4 deletions.
14 changes: 11 additions & 3 deletions lib/skate/open_route_service_api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ defmodule Skate.OpenRouteServiceAPI do
## Examples
iex> Skate.OpenRouteServiceAPI.directions([%{"lat" => 0, "lon" => 10}, %{"lat" => 1, "lon" => 10}])
{:error, %{"message" => "Invalid API Key"}}
{:error, %{type: :unknown}}
"""
@spec directions(list()) :: {:ok, DirectionsResponse.t()} | {:error, any()}
def directions([]), do: {:ok, %DirectionsResponse{}}
Expand All @@ -65,8 +65,8 @@ defmodule Skate.OpenRouteServiceAPI do
{:ok, payload} ->
parse_directions(payload)

error ->
error
{:error, error} ->
parse_error(error)
end
end

Expand Down Expand Up @@ -97,6 +97,14 @@ defmodule Skate.OpenRouteServiceAPI do
}}
end

# Convert API Error codes into specific errors for the frontend to handle
# https://giscience.github.io/openrouteservice/api-reference/error-codes

# 2010: Point was not found.
defp parse_error(%{"code" => 2010}), do: {:error, %{type: :no_route}}

defp parse_error(_error), do: {:error, %{type: :unknown}}

defp client(), do: Application.get_env(:skate, Skate.OpenRouteServiceAPI)[:client]

defp map_type(type_id) do
Expand Down
3 changes: 3 additions & 0 deletions lib/skate/open_route_service_api/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ defmodule Skate.OpenRouteServiceAPI.Client do
{:ok, %HTTPoison.Response{status_code: 400, body: body}} ->
{:error, Jason.decode!(body)["error"]}

{:ok, %HTTPoison.Response{status_code: 404, body: body}} ->
{:error, Jason.decode!(body)["error"]}

{:error, %HTTPoison.Error{}} ->
{:error, "unknown"}
end
Expand Down
32 changes: 32 additions & 0 deletions test/skate/open_route_service_api_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,36 @@ defmodule Skate.OpenRouteServiceAPITest do
%{"lat" => 0, "lon" => 1}
])
end

test "unknown errors from ORS return `type: :unknown`" do
expect(
Skate.OpenRouteServiceAPI.MockClient,
:get_directions,
fn _ ->
{:error, %{"code" => -1}}
end
)

assert {:error, %{type: :unknown}} =
Skate.OpenRouteServiceAPI.directions([
%{"lat" => 0, "lon" => 0},
%{"lat" => 0, "lon" => 1}
])
end

test "point not found errors from ORS return `type: :no_route`" do
expect(
Skate.OpenRouteServiceAPI.MockClient,
:get_directions,
fn _ ->
{:error, %{"code" => 2010}}
end
)

assert {:error, %{type: :no_route}} =
Skate.OpenRouteServiceAPI.directions([
%{"lat" => 0, "lon" => 0},
%{"lat" => 0, "lon" => 1}
])
end
end
19 changes: 18 additions & 1 deletion test/skate_web/controllers/detour_route_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,24 @@ defmodule SkateWeb.DetourRouteControllerTest do
coordinates: [%{"lat" => 1, "lon" => 100}, %{"lat" => 2, "lon" => 101}]
)

assert json_response(conn, 500)
assert %{"error" => %{"type" => "unknown"}} = json_response(conn, 500)
end

@tag :authenticated
test "returns a 500-level response with type: :no_route when ORS reports point not found error",
%{
conn: conn
} do
expect(Skate.OpenRouteServiceAPI.MockClient, :get_directions, fn _ ->
{:error, %{"code" => 2010}}
end)

conn =
post(conn, ~p"/api/detours/directions",
coordinates: [%{"lat" => 1, "lon" => 100}, %{"lat" => 2, "lon" => 101}]
)

assert %{"error" => %{"type" => "no_route"}} = json_response(conn, 500)
end
end
end

0 comments on commit 80e31cf

Please sign in to comment.