     ""
   end
 
-  def blame(
-        %{
-          module: module,
-          function: function,
-          arity: arity,
-          kind: kind,
-          args: args,
-          clauses: clauses
-        },
-        inspect_fun,
-        ast_fun
-      ) do
+  def blame(exception, inspect_fun, ast_fun) do
+    %{module: module, function: function, arity: arity, kind: kind, args: args, clauses: clauses} =
+      exception
+
     mfa = Exception.format_mfa(module, function, arity)
 
     formatted_args =

    end
  end

  defp blame_match(%{match?: true, node: node}, _), do: Macro.to_string(node)
  defp blame_match(%{match?: false, node: node}, _), do: "-" <> Macro.to_string(node) <> "-"
  defp blame_match(_, string), do: string


  This operation is potentially expensive, as it reads data
  from the filesystem, parse beam files, evaluates code and
  so on.

  If the exception module implements the optional `c:blame/2`
  callbak, it will be invoked to perform the computation.
  """
  @spec blame(:error, any, stacktrace) :: {t, stacktrace}
  @spec blame(non_error_kind, payload, stacktrace) :: {payload, stacktrace} when payload: var
  def blame(kind, error, stacktrace)

  def blame(:error, error, stacktrace) do
    %module{} = struct = normalize(:error, error, stacktrace)

    if Code.ensure_loaded?(module) and function_exported?(module, :blame, 2) do
      module.blame(struct, stacktrace)
    else
      {struct, stacktrace}
    end
  end

  def blame(_kind, reason, stacktrace) do
    {reason, stacktrace}
  end

  @doc """
