diff --git a/lib/jellyfish/component.ex b/lib/jellyfish/component.ex index cbf7d85..c8095ee 100644 --- a/lib/jellyfish/component.ex +++ b/lib/jellyfish/component.ex @@ -62,8 +62,8 @@ defmodule Jellyfish.Component do tracks: Enum.map(tracks, &Track.from_json/1) } - _other -> - raise StructureError + unknown_structure -> + raise StructureError, unknown_structure end end diff --git a/lib/jellyfish/exception.ex b/lib/jellyfish/exception.ex index e1dba59..75fc349 100644 --- a/lib/jellyfish/exception.ex +++ b/lib/jellyfish/exception.ex @@ -5,10 +5,11 @@ defmodule Jellyfish.Exception do defexception [:message] @impl true - def exception(_opts) do + def exception(structure) do msg = """ Received server response or notification with unexpected structure. Make sure you are using correct combination of Jellyfish and SDK versions. + Passed structure: #{inspect(structure)} """ %__MODULE__{message: msg} diff --git a/lib/jellyfish/health.ex b/lib/jellyfish/health.ex index 8453670..991f50d 100644 --- a/lib/jellyfish/health.ex +++ b/lib/jellyfish/health.ex @@ -11,8 +11,6 @@ defmodule Jellyfish.Health do ``` """ - alias Tesla.Env - alias Jellyfish.{Client, Utils} alias Jellyfish.Exception.StructureError @@ -54,13 +52,9 @@ defmodule Jellyfish.Health do """ @spec check(Client.t()) :: {:ok, t()} | {:error, atom() | String.t()} def check(client) do - with {:ok, %Env{status: 200, body: body}} <- Tesla.get(client.http_client, "/health"), - {:ok, data} <- Map.fetch(body, "data"), + with {:ok, data} <- Utils.make_get_request!(client, "/health"), result <- from_json(data) do {:ok, result} - else - :error -> raise StructureError - error -> Utils.handle_response_error(error) end end @@ -87,8 +81,8 @@ defmodule Jellyfish.Health do } } - _other -> - raise StructureError + unknown_structure -> + raise StructureError, unknown_structure end end diff --git a/lib/jellyfish/peer.ex b/lib/jellyfish/peer.ex index 969866d..64bd8ff 100644 --- a/lib/jellyfish/peer.ex +++ b/lib/jellyfish/peer.ex @@ -72,8 +72,8 @@ defmodule Jellyfish.Peer do metadata: metadata } - _other -> - raise StructureError + unknown_structure -> + raise StructureError, unknown_structure end end diff --git a/lib/jellyfish/recording.ex b/lib/jellyfish/recording.ex index a5e0cb7..ce741e0 100644 --- a/lib/jellyfish/recording.ex +++ b/lib/jellyfish/recording.ex @@ -10,7 +10,6 @@ defmodule Jellyfish.Recording do ``` """ - alias Jellyfish.Exception.StructureError alias Jellyfish.{Client, Utils} alias Tesla.Env @@ -24,14 +23,7 @@ defmodule Jellyfish.Recording do """ @spec get_list(Client.t()) :: {:ok, [id()]} | {:error, String.t()} def get_list(client) do - with {:ok, %Env{status: 200, body: body}} <- - Tesla.get(client.http_client, "/recording"), - {:ok, data} <- Map.fetch(body, "data") do - {:ok, data} - else - :error -> raise StructureError - error -> Utils.handle_response_error(error) - end + Utils.make_get_request!(client, "/recording") end @doc """ diff --git a/lib/jellyfish/room.ex b/lib/jellyfish/room.ex index 9a57f0d..70fc5f7 100644 --- a/lib/jellyfish/room.ex +++ b/lib/jellyfish/room.ex @@ -102,13 +102,9 @@ defmodule Jellyfish.Room do """ @spec get_all(Client.t()) :: {:ok, [t()]} | {:error, atom() | String.t()} def get_all(client) do - with {:ok, %Env{status: 200, body: body}} <- Tesla.get(client.http_client, "/room"), - {:ok, data} <- Map.fetch(body, "data"), + with {:ok, data} <- Utils.make_get_request!(client, "/room"), result <- Enum.map(data, &from_json/1) do {:ok, result} - else - :error -> raise StructureError - error -> Utils.handle_response_error(error) end end @@ -117,14 +113,9 @@ defmodule Jellyfish.Room do """ @spec get(Client.t(), id()) :: {:ok, t()} | {:error, atom() | String.t()} def get(client, room_id) do - with {:ok, %Env{status: 200, body: body}} <- - Tesla.get(client.http_client, "/room/#{room_id}"), - {:ok, data} <- Map.fetch(body, "data"), + with {:ok, data} <- Utils.make_get_request!(client, "/room/#{room_id}"), result <- from_json(data) do {:ok, result} - else - :error -> raise StructureError - error -> Utils.handle_response_error(error) end end @@ -139,26 +130,18 @@ defmodule Jellyfish.Room do """ @spec create(Client.t(), options()) :: {:ok, t(), String.t()} | {:error, atom() | String.t()} def create(client, opts \\ []) do - with {:ok, %Env{status: 201, body: body}} <- - Tesla.post( - client.http_client, - "/room", - %{ - "roomId" => Keyword.get(opts, :room_id), - "maxPeers" => Keyword.get(opts, :max_peers), - "videoCodec" => Keyword.get(opts, :video_codec), - "webhookUrl" => Keyword.get(opts, :webhook_url), - "peerlessPurgeTimeout" => Keyword.get(opts, :peerless_purge_timeout) - } - ), - {:ok, data} <- Map.fetch(body, "data"), - {:ok, room_json} <- Map.fetch(data, "room"), - {:ok, jellyfish_address} <- Map.fetch(data, "jellyfish_address"), + with {:ok, data} <- + Utils.make_post_request!(client, "/room", %{ + "roomId" => Keyword.get(opts, :room_id), + "maxPeers" => Keyword.get(opts, :max_peers), + "videoCodec" => Keyword.get(opts, :video_codec), + "webhookUrl" => Keyword.get(opts, :webhook_url), + "peerlessPurgeTimeout" => Keyword.get(opts, :peerless_purge_timeout) + }), + room_json <- Map.fetch!(data, "room"), + jellyfish_address <- Map.fetch!(data, "jellyfish_address"), result <- from_json(room_json) do {:ok, result, jellyfish_address} - else - :error -> raise StructureError - error -> Utils.handle_response_error(error) end end @@ -181,23 +164,16 @@ defmodule Jellyfish.Room do def add_peer(client, room_id, peer) do peer = if is_atom(peer), do: struct!(peer), else: peer - with {:ok, %Env{status: 201, body: body}} <- - Tesla.post( - client.http_client, - "/room/#{room_id}/peer", - %{ - "type" => Peer.string_from_options(peer), - "options" => - Map.from_struct(peer) - |> Map.new(fn {k, v} -> {snake_case_to_camel_case(k), v} end) - } - ), - {:ok, %{"peer" => peer, "token" => token}} <- Map.fetch(body, "data"), + with {:ok, data} <- + Utils.make_post_request!(client, "/room/#{room_id}/peer", %{ + "type" => Peer.string_from_options(peer), + "options" => + Map.from_struct(peer) + |> Map.new(fn {k, v} -> {snake_case_to_camel_case(k), v} end) + }), + %{"peer" => peer, "token" => token} <- data, result <- Peer.from_json(peer) do {:ok, result, token} - else - :error -> raise StructureError - error -> Utils.handle_response_error(error) end end @@ -295,8 +271,8 @@ defmodule Jellyfish.Room do peers: Enum.map(peers, &Peer.from_json/1) } - _other -> - raise StructureError + unknown_structure -> + raise StructureError, unknown_structure end end diff --git a/lib/jellyfish/track.ex b/lib/jellyfish/track.ex index a875d3c..a192b67 100644 --- a/lib/jellyfish/track.ex +++ b/lib/jellyfish/track.ex @@ -50,8 +50,8 @@ defmodule Jellyfish.Track do metadata: metadata } - _other -> - raise StructureError + unknown_structure -> + raise StructureError, unknown_structure end end diff --git a/lib/jellyfish/utils.ex b/lib/jellyfish/utils.ex index ca4401b..352f5ce 100644 --- a/lib/jellyfish/utils.ex +++ b/lib/jellyfish/utils.ex @@ -24,6 +24,29 @@ defmodule Jellyfish.Utils do {server_address, server_api_token, secure?} end + def make_get_request!(client, path) do + make_request!(200, :get, client.http_client, path) + end + + def make_post_request!(client, path, request_body) do + make_request!(201, :post, client.http_client, path, request_body) + end + + defp make_request!(status_code, method, client, path, request_body \\ nil) do + with {:ok, %Env{status: ^status_code, body: body}} <- + Tesla.request(client, url: path, method: method, body: request_body) do + data = + case Map.fetch(body, "data") do + {:ok, data} -> data + :error -> raise StructureError, body + end + + {:ok, data} + else + error -> handle_response_error(error) + end + end + @spec check_prefixes(String.t()) :: nil def check_prefixes(server_address) do if String.starts_with?(server_address, @protocol_prefixes), do: raise(ProtocolPrefixError) @@ -35,7 +58,7 @@ defmodule Jellyfish.Utils do def handle_response_error({:ok, %Env{body: %{"errors" => error}}}), do: {:error, "Request failed: #{error}"} - def handle_response_error({:ok, %Env{body: _body}}), do: raise(StructureError) + def handle_response_error({:ok, %Env{body: body}}), do: raise(StructureError, body) def handle_response_error({:error, :component_validation}), do: raise(OptionsError) def handle_response_error({:error, reason}), do: {:error, reason} end diff --git a/test/jellyfish/room_test.exs b/test/jellyfish/room_test.exs index ffbf721..7df5ef6 100644 --- a/test/jellyfish/room_test.exs +++ b/test/jellyfish/room_test.exs @@ -106,7 +106,9 @@ defmodule Jellyfish.RoomTest do test "invalid token" do client = Client.new(server_api_token: "invalid" <> @server_api_token) - assert {:error, _reason} = Room.create(client, max_peers: @max_peers) + + assert {:error, _reason} = + Room.create(client, max_peers: @max_peers) end end