Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
ryanbjones opened this issue Aug 20, 2019 · 0 comments · Fixed by #34
Closed

Comments

@ryanbjones
Copy link
Contributor

ryanbjones commented Aug 20, 2019

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant