-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathexceptions.ex
More file actions
138 lines (116 loc) · 3.93 KB
/
exceptions.ex
File metadata and controls
138 lines (116 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# credo:disable-for-next-line
defmodule Thrift.TApplicationException do
@moduledoc """
Application-level exception
"""
@type t() :: %__MODULE__{message: String.t, type: exception_type()}
@enforce_keys [:message, :type]
defexception message: "unknown", type: :unknown
# This list represents the set of well-known TApplicationException types.
# We primarily use their atom names, but we also need their standardized
# integer values for representing these values in their serialized form.
@exception_types [
unknown: 0,
unknown_method: 1,
invalid_message_type: 2,
wrong_method_name: 3,
bad_sequence_id: 4,
missing_result: 5,
internal_error: 6,
protocol_error: 7,
invalid_transform: 8,
invalid_protocol: 9,
unsupported_client_type: 10,
loadshedding: 11,
timeout: 12,
injected_failure: 13
]
@typedoc """
Exception types
"""
@type exception_type :: unquote(Enum.reduce(@exception_types, fn {type, _}, acc -> {:|, [] , [type, acc]} end))
def exception(args) when is_list(args) do
type = normalize_type(Keyword.fetch!(args, :type))
message = args[:message] || Atom.to_string(type)
%__MODULE__{message: message, type: type}
end
@doc """
Converts an exception type to its integer identifier.
"""
@spec type_id(exception_type()) :: non_neg_integer()
def type_id(type)
for {type, id} <- @exception_types do
def type_id(unquote(type)), do: unquote(id)
defp normalize_type(unquote(id)), do: unquote(type)
defp normalize_type(unquote(type)), do: unquote(type)
end
defp normalize_type(type) when is_integer(type), do: :unknown
defprotocol SerDe do
@moduledoc """
Serialize and deserialize protocol for `Thrift.TApplicationException.t`
"""
@doc """
Serialize `Thrift.TApplicationException.t` with a protocol payload.
"""
@spec serialize(payload, TApplicationException.t()) :: payload when payload: var
def serialize(payload, err)
@doc """
Deserialize `Thrift.TApplication.t` with a protocol payload.
"""
@spec deserialize(payload) :: {TApplicationException.t(), payload} | :error when payload: var
def deserialize(payload)
@doc """
Deserialize `Thrift.TApplication.t` with a protocol payload and default values.
"""
@spec deserialize(payload, TApplicationException.t()) :: {TApplicationException.t(), payload} | :error when payload: var
def deserialize(payload, err)
end
defimpl Thrift.Serializable do
def serialize(err, payload), do: SerDe.serialize(payload, err)
def deserialize(err, payload), do: SerDe.deserialize(payload, err)
end
end
defmodule Thrift.ConnectionError do
@enforce_keys [:reason]
defexception [:reason]
def message(%{reason: reason}) when reason in [:closed, :timeout] do
"Connection error: #{reason}"
end
def message(%{reason: reason}) do
# :ssl can format both ssl and tcp (posix) errors
"Connection error: #{:ssl.format_error(reason)} (#{reason})"
end
end
defmodule Thrift.Union.TooManyFieldsSetError do
@moduledoc """
This exception occurs when a Union is serialized and more than one
field is set.
"""
@enforce_keys [:message, :set_fields]
defexception message: nil, set_fields: nil
end
defmodule Thrift.FileParseError do
@moduledoc """
This exception occurs when a thrift file fails to parse
"""
@enforce_keys [:message]
defexception message: nil
# Exception callback, should not be called by end user
@doc false
@spec exception({Thrift.Parser.FileRef.t(), term}) :: Exception.t()
def exception({file_ref, error}) do
msg = "Error parsing thrift file #{file_ref.path} #{format_error(error)}"
%__MODULE__{message: msg}
end
# display the line number if we get it
defp format_error({line_no, message}) do
"on line #{line_no}: #{message}"
end
defp format_error(error) do
": #{inspect(error)}"
end
end
defmodule Thrift.InvalidValueError do
@enforce_keys [:message]
defexception message: nil
end