Elixir: Correct way of printing __STACKTRACE__
Asked Answered
I

1

15

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
Intuitive answered 3/12, 2018 at 7:55 Comment(0)
I
25

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
Intuitive answered 3/12, 2018 at 8:0 Comment(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__).Defroster

© 2022 - 2024 — McMap. All rights reserved.