12

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
Sheharyar
  • 73,588
  • 21
  • 168
  • 215

1 Answers1

23

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
Sheharyar
  • 73,588
  • 21
  • 168
  • 215
  • 1
    What is cool with `Exception.format/3` is that it takes the same arguments as `catch` does. Thus `catch kind, payload ->` maps onto `Exception.format(kind, payload, __STACKTRACE__)`. – Ludovic Kuty Jul 05 '23 at 09:28