Packages
rockbox_ex
0.1.0
Idiomatic Elixir SDK for Rockbox — pipe-friendly, builder-friendly, with real-time event subscriptions and a plugin system.
Current section
Files
Jump to
Current section
Files
lib/rockbox/error.ex
defmodule Rockbox.Error do
@moduledoc """
Base exception for the Rockbox SDK.
Two specialised subclasses are raised in practice:
* `Rockbox.NetworkError` — the HTTP request failed or returned a non-2xx
status code (rockboxd unreachable, refused connection, timeout, …).
* `Rockbox.GraphQLError` — rockboxd answered with a structured GraphQL
error response. The original error list is available on the
`:errors` field.
Both inherit from `Rockbox.Error`, so a single rescue clause catches every
SDK-originated failure:
try do
Rockbox.Playback.play!(client)
rescue
e in Rockbox.NetworkError -> Logger.error("offline: \#{e.message}")
e in Rockbox.GraphQLError -> Logger.error("server error: \#{e.message}")
e in Rockbox.Error -> Logger.error("rockbox: \#{e.message}")
end
"""
defexception [:message, :cause]
@type t :: %__MODULE__{message: String.t(), cause: term() | nil}
end
defmodule Rockbox.NetworkError do
@moduledoc "Raised when the HTTP layer cannot reach rockboxd."
defexception [:message, :cause]
@type t :: %__MODULE__{message: String.t(), cause: term() | nil}
end
defmodule Rockbox.GraphQLError do
@moduledoc "Raised when rockboxd returns a structured GraphQL error response."
defexception [:message, :errors]
@type error_detail :: %{
required(:message) => String.t(),
optional(:path) => [String.t() | non_neg_integer()],
optional(:locations) => [%{line: non_neg_integer(), column: non_neg_integer()}],
optional(:extensions) => map()
}
@type t :: %__MODULE__{message: String.t(), errors: [error_detail()]}
@impl true
def exception(errors) when is_list(errors) do
%__MODULE__{
message: errors |> Enum.map_join("; ", &Map.get(&1, :message, "GraphQL error")),
errors: errors
}
end
end