appsignal-elixir icon indicating copy to clipboard operation
appsignal-elixir copied to clipboard

backtrace omits function arguments for "no function clause matching" errors

Open dvic opened this issue 3 years ago • 8 comments

For example, an example backtrace in our logs like this:

  ** (FunctionClauseError) no function clause matching in Vivo.check_valid_from/2
        (vivo 0.1.0) lib/vivo/vivo.ex:97: Vivo.check_valid_from(nil, ~U[2021-03-26 16:25:09.835557Z])

is rendered in Appsignal like lib/vivo/vivo.ex:97 Vivo.check_valid_from/2.

dvic avatar Mar 29 '21 08:03 dvic

Thanks for reporting. We strip out the actual arguments because they could contain personally identifiable information or secrets. How would having this data help you?

thijsc avatar Mar 31 '21 11:03 thijsc

Ah I see. Well in some cases, you can guess where it went wrong with the match (like in the above example, you can guess one of the parameters had to be nil to fail the match for example). However, in some cases, it's crucial to have the arguments printed because you can't always figure out why no function clause matched. The argument could be a more complex value, like a struct, where one particular (nested) field does not match the pattern in the function signature.

dvic avatar Mar 31 '21 11:03 dvic

We were just discussing this case. What might be useful is showing the type of the arguments. Would that help you?

thijsc avatar Mar 31 '21 12:03 thijsc

Yeah that would be better than nothing for sure, but I can't say in what percentage of the cases that would actually be enough to find the root cause of the problem.

dvic avatar Apr 15 '21 10:04 dvic

Let's see if we can show the types of arguments. Moving to To do.

tombruijn avatar Apr 26 '21 11:04 tombruijn

This would be helpful for me as well. Could you perhaps make it configurable so we could decide if we wanted to have those params shown in Appsignal?

almirsarajcic avatar May 18 '21 16:05 almirsarajcic

In case anyone is interested in a workaround:

defmodule FooWeb.Appsignal.UnhandledLiveViewHandleEventReporter do
  defmacro __using__(_options) do
    quote do
      @before_compile FooWeb.Appsignal.UnhandledLiveViewHandleEventReporter
    end
  end

  # the following is inserted at the bottom of each liveview,
  # so any local handle_event definitions will take preference
  # over this one
  defmacro __before_compile__(_env) do
    quote generated: true do
      @_omit_unhandled_event_params Module.get_attribute(__MODULE__, :omit_unhandled_event_params, true)

      def handle_event(op, params, %Phoenix.LiveView.Socket{} = socket) do
        raise %FunctionClauseError{
          module: __MODULE__,
          function: :handle_event,
          arity: 3,
          kind: :error,
          args: [
            op,
            if(@_omit_unhandled_event_params, do: :hidden, else: params),
            :omitted
          ],
          clauses: []
        }
      end
    end
  end
end

To include in all views/components, add use FooWeb.Appsignal.UnhandledLiveViewHandleEventReporter to the live_view/0 and live_component/0 functions of FooWeb. The first argument is always considered to be safe. The second argument (params) can be marked as safe for a view/component by declaring a module attribute, @omit_unhandled_event_params false - otherwise it is omitted from the error report by default.

hlindset avatar Jan 14 '22 15:01 hlindset

https://app.intercom.com/a/apps/yzor8gyw/inbox/inbox/conversation/16410700131606 Specifically from this point on: https://app.intercom.com/a/apps/yzor8gyw/inbox/inbox/conversation/16410700131606#part_id=comment-16410700131606-15852776431

tombruijn avatar Jul 19 '22 08:07 tombruijn

This issue, as it was originally opened, was already resolved with the original implementation of backtrace cleaning (https://github.com/appsignal/appsignal-elixir/pull/804)

I'm closing this issue. Feel free to reopen or open a new issue for future backtrace cleaning problems.

unflxw avatar Jun 15 '23 15:06 unflxw