arjan / decorator

Function decorators for Elixir

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using two different decorator modules in the same file creates duplicate functions

ryanbjones opened this issue · comments

I'm trying to implement a custom decorator to apply the logger_metadata to spawned batch processes from Absinthe's batch. I have the following module

defmodule LoggerDecorator do
  @moduledoc """
  Makes it so that async functions that have been invoked can find the parent caller and
  put the request_id on the logger, which will enhance debugging
  """
  use Decorator.Define, [apply_request_id_to_logger: 0]
  require Logger

  def apply_request_id_to_logger(body, _context) do
    quote do
      parent_pid =
        :"$callers"
        |> Process.get()
        |> List.last()

      {_, metadata} = Process.info(parent_pid)[:dictionary][:logger_metadata]
      request_id = Keyword.get(metadata, :request_id, nil)
      Logger.metadata([request_id: request_id])

      unquote(body)
    end
  end
end

We use Appsignal, so at the top of our resolver file I have

defmodule MyApp.Resolver.Template do 
  use Appsignal.Instrumentation.Decorators
  use LoggerDecorator

 @decorate apply_request_id_to_logger()
  def all(location_uids, organization_uid, user_uid, types \\ Template.visible_template_types()) do 
  end

  @decorate transaction_event()
  def update(params) do
  end
end

which will throw the error

== Compilation error in file lib/black_mamba/templates.ex ==
** (CompileError) lib/black_mamba/templates.ex:1: def all/4 defines defaults multiple times. Elixir allows defaults to be declared once per definition. Instead of:

    def foo(:first_clause, b \\ :default) do ... end
    def foo(:second_clause, b \\ :default) do ... end

In other files where a function does not have a default, but both decorator modules are used, I get a slew of

warning: this clause cannot match because a previous clause at line 1 always matches
  web/resolver/location.ex:1

On Elixir 1.9, decorator 1.2.4