Packages
honeybadger
0.3.1
0.28.0
0.27.0
0.26.0
0.25.0
0.24.1
0.24.0
0.23.0
0.22.1
0.22.0
0.21.0
0.20.0
0.19.0
0.18.1
0.18.0
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.0
0.14.1
0.14.0
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.8.0
0.7.0
0.7.0-beta
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.0
0.3.1
0.3.0
0.2.0
0.1.2
0.1.1
0.1.0
Elixir client, Plug and error_logger for integrating with the Honeybadger.io exception tracker"
Current section
Files
Jump to
Current section
Files
lib/honeybadger/plug.ex
defmodule Honeybadger.Plug do
alias Honeybadger.Utils
defmacro __using__(_env) do
quote do
import Honeybadger.Plug
use Plug.ErrorHandler
require Honeybadger
# Exceptions raised on non-existant Plug routes are ignored
defp handle_errors(conn, %{reason: %FunctionClauseError{function: :do_match}} = ex) do
nil
end
if :code.is_loaded(Phoenix) do
# Exceptions raised on non-existant Phoenix routes are ignored
defp handle_errors(conn, %{reason: %Phoenix.Router.NoRouteError{}} = ex) do
nil
end
end
defp handle_errors(conn, %{kind: _kind, reason: exception, stack: stack}) do
metadata = %{plug_env: build_plug_env(conn, __MODULE__),
context: Honeybadger.context()}
Honeybadger.notify(exception, metadata, stack)
end
end
end
def build_plug_env(%Plug.Conn{} = conn, mod) do
session = %{}
conn = try do
Plug.Conn.fetch_session(conn)
session = conn.session
rescue
e in [ArgumentError, KeyError] ->
# just return conn and move on
conn
end
conn = conn
|> Plug.Conn.fetch_cookies
|> Plug.Conn.fetch_query_params
%{url: conn.request_path,
component: Utils.strip_elixir_prefix(mod),
action: "",
params: conn.params,
session: session,
cgi_data: build_cgi_data(conn)}
end
def build_cgi_data(%Plug.Conn{} = conn) do
rack_env_http_vars = Enum.reduce conn.req_headers, %{}, &header_to_rack_format/2
cgi_data = %{
"REQUEST_METHOD" => conn.method,
"PATH_INFO" => Enum.join(conn.path_info, "/"),
"QUERY_STRING" => conn.query_string,
"SCRIPT_NAME" => Enum.join(conn.script_name, "/"),
"REMOTE_ADDR" => get_remote_addr(conn.remote_ip),
"REMOTE_PORT" => get_remote_port(conn.peer),
"SERVER_ADDR" => "127.0.0.1",
"SERVER_NAME" => Application.get_env(:honeybadger, :hostname),
"SERVER_PORT" => conn.port,
"CONTENT_LENGTH" => Plug.Conn.get_req_header(conn, "content-length"),
"ORIGINAL_FULLPATH" => conn.request_path
}
Map.merge(rack_env_http_vars, cgi_data)
end
def get_remote_addr(addr), do: :inet.ntoa(addr) |> List.to_string
def get_remote_port({_, port}), do: port
def header_to_rack_format({header, value}, acc) do
header = "HTTP_" <> String.upcase(header) |> String.replace("-", "_")
Map.put(acc, header, value)
end
end