Current section
Files
Jump to
Current section
Files
lib/twirp/error.ex
defmodule Twirp.Error do
@moduledoc """
This module defines the different error codes as specified in
https://twitchtv.github.io/twirp/docs/spec_v5.html#error-codes.
We provide a function for each error code to that its easy for users to return
errors in their handlers.
"""
@error_code_to_http_status %{
# RequestTimeout
canceled: 408,
# BadRequest
invalid_argument: 400,
# RequestTimeout
deadline_exceeded: 408,
# Not Found
not_found: 404,
# Not Found
bad_route: 404,
# Conflict
already_exists: 409,
# Forbidden
permission_denied: 403,
# Unauthorized
unauthenticated: 401,
# Forbidden
resource_exhausted: 403,
# Precondition Failed
failed_precondition: 412,
# Conflict
aborted: 409,
# Bad Request
out_of_range: 400,
# Internal Server Error
internal: 500,
# Internal Server Error
unknown: 500,
# Not Implemented
unimplemented: 501,
# Service Unavailable
unavailable: 503,
# Internal Server Error
data_loss: 500
}
@error_codes Map.keys(@error_code_to_http_status)
@error_code_strings for code <- @error_codes, do: Atom.to_string(code)
defexception ~w|code msg meta|a
@type t :: %__MODULE__{
code: atom(),
msg: binary(),
meta: %{atom() => binary()}
}
for code <- @error_codes do
def unquote(code)(msg, meta \\ []) do
new(unquote(code), msg, meta)
end
end
def valid_code?(code) when is_atom(code), do: code in @error_codes
def valid_code?(code) when is_binary(code), do: code in @error_code_strings
def code_to_status(code) when code in @error_codes do
@error_code_to_http_status[code]
end
def new(code, msg, meta \\ []) do
msg = String.replace_prefix(msg, "#{meta["argument"]} ", "")
%__MODULE__{code: code, msg: msg, meta: Enum.into(meta, %{})}
end
@impl true
def message(%__MODULE__{msg: msg}), do: msg
defimpl Jason.Encoder do
def encode(struct, opts) do
map =
if struct.meta == %{} do
Map.take(struct, [:code, :msg])
else
Map.take(struct, [:code, :msg, :meta])
end
Jason.Encode.map(map, opts)
end
end
end