Search code examples
exceptionelixirstack-tracerescue

Elixir: Correct way of printing __STACKTRACE__


I know we can get the full stacktrace using __STACKTRACE__ in a catch/rescue block in , but what's the correct way of printing it? In my case, I rescue from an error but I still want to log it to console. This is what I'm doing right now:

def unreliable_method(item) do
  # Do something with `item`
  :ok
rescue
  _err ->
    Logger.error("Failed for item: #{inspect(item)}")
    Logger.error(inspect(__STACKTRACE__))
    {:error, :processing_failed}
end

Solution

  • Just the Stacktrace

    This was answered by Michał Muskała on the official elixir github issue:

    The canonical way would be to use Exception.format_stacktrace/1

    From the docs, it's clear that we don't need to explicitly pass __STACKTRACE__ as an argument to the method when still inside the rescue block. It's automatically retrieved using Process.info:

    Logger.error(Exception.format_stacktrace())
    

    Full Error and Stacktrace

    Michal's comment helped me find Exception.format/3, that formats the error itself and its complete stacktrace, and that seemed more appropriate for my usecase:

    def unreliable_method do
      # do something
      :ok
    rescue
      err ->
        Logger.error(Exception.format(:error, err, __STACKTRACE__))
        {:error, :processing_failed}
    end