Packages
tds
2.3.0-rc.0
2.3.8
2.3.7
2.3.6
2.3.5
2.3.4
2.3.2
2.3.1
2.3.0
2.3.0-rc.1
2.3.0-rc.0
2.2.0
2.1.3
2.1.2
2.1.1
2.1.0
2.0.4
2.0.3
2.0.2
2.0.1
2.0.1-rc2
2.0.1-rc1
2.0.0
retired
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.0
1.0.19
1.0.18
1.0.17
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.0
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Microsoft SQL Server client (Elixir implementation of the MS TDS protocol)
Current section
Files
Jump to
Current section
Files
lib/tds/error.ex
defmodule Tds.Error do
@moduledoc """
Defines the `Tds.Error` struct.
The struct has two fields:
* `:message`: expected to be a string
* `:mssql`: expected to be a keyword list with the fields `line_number`,
`number` and `msg_text`
## Usage
iex> raise Tds.Error
** (Tds.Error) An error occured.
iex> raise Tds.Error, "some error"
** (Tds.Error) some error
iex> raise Tds.Error, line_number: 10, number: 8, msg_text: "some error"
** (Tds.Error) Line 10 (8): some error
"""
@type error_details :: %{line_number: integer(), number: integer(), msg_text: String.t()}
@type t :: %__MODULE__{message: String.t(), mssql: error_details}
defexception [:message, :mssql]
def exception(message) when is_binary(message) or is_atom(message) do
%__MODULE__{message: message}
end
def exception(line_number: line_number, number: number, msg_text: msg) do
%__MODULE__{
mssql: %{
line_number: line_number,
number: number,
msg_text: msg
}
}
end
def exception(_) do
%__MODULE__{message: "An error occured."}
end
@spec message(%__MODULE__{}) :: String.t()
def message(%__MODULE__{mssql: mssql}) when is_map(mssql) do
"Line #{mssql[:line_number]} (Error #{mssql[:number]}): #{mssql[:msg_text]}"
end
def message(%__MODULE__{message: message}) when is_binary(message) do
message
end
@external_resource errcodes_path = Path.join(__DIR__, "errors.csv")
errcodes =
for line <- File.stream!(errcodes_path) do
[type, code, regex] = String.split(line, ",", trim: true)
type = String.to_atom(type)
code = code |> String.trim()
regex = String.replace_trailing(regex, "\n", "")
if code == nil do
raise CompileError, "Error code must be integer value"
end
{code, {type, regex}}
end
Enum.group_by(errcodes, &elem(&1, 0), &elem(&1, 1))
|> Enum.map(fn {code, type_regexes} ->
{error_code, ""} = Integer.parse(code)
def get_constraint_violations(unquote(error_code), message) do
constraint_checks =
Enum.map(unquote(type_regexes), fn {key, val} ->
{key, Regex.compile!(val)}
end)
extract = fn {key, test}, acc ->
concatenate_match = fn [match], acc -> [{key, match} | acc] end
case Regex.scan(test, message, capture: :all_but_first) do
[] -> acc
matches -> Enum.reduce(matches, acc, concatenate_match)
end
end
Enum.reduce(constraint_checks, [], extract)
end
end)
def get_constraint_violations(_, _) do
[]
end
end
defmodule Tds.ConfigError do
defexception message: "Tds configuration error."
def exception(message) when is_binary(message) or is_atom(message) do
%__MODULE__{message: message}
end
end