Calling super for GenServer callback handle_info/2 is deprecated, what is the proper solution?

this is related to an earlier post I made.

In that post I ask for a generic solution to call the an overridden function and super is suggested as the answer.

However, to my surprise, it actually does not work for the particular case of handle_info of GenServer, and a warning msg Calling super for GenServer callback handle_info/2 is deprecated is shown.

I did some googling but could find a proper solution, any suggestions/ideas?

example code:

defmodule Foo do
  use GenServer

  # this generate warning msg
  # 'Calling super for GenServer callback handle_info/2 is deprecated'
  def handle_info(msg, state), do: super(msg, state)
end

This is the default injected handle_info/2 implementation: elixir/gen_server.ex at main · elixir-lang/elixir · GitHub

Basically it just does log an error message sayingSomeModule #PID<0.111.0> received unexpected message in handle_info/2: :some_message.

I assume it is deprecated because unexpected messages should be handled by explicit logging, or by not defining a function clause accepting them and crash.

In your code example, as your function only calls super/2, you can just remove it altogether and you are good. If you want to add your own handle_info clauses and still want to log unexpected messages, you should do it explicitely.

1 Like

Thanks a lot for the suggestion and speculation on why it is deprecated, I think it does make sense.

And ya, I have also implemented a very similar catch-all/fallback handler, was just unsure if there are some more intricate bit about the deprecation I should be aware :smiley:

Looking at the source code you linked, I have a followup question:
It seems they are doing some sort of structured logging there, is that shape a standardized error/report structure in Elixir? I would adopt it in my code if it is standardized or a common practice.

        :logger.error(
          %{
            label: {GenServer, :no_handle_info},
            report: %{
              module: __MODULE__,
              message: msg,
              name: proc
            }
          },
          %{
            domain: [:otp, :elixir],
            error_logger: %{tag: :error_msg},
            report_cb: &GenServer.format_report/1
          }
        )

Sorry I do not know much about the erlang logger. In Elixir you generally log a string and metadata.

icic, thanks anyway.