Using two different decorator modules in the same file creates duplicate functions
ryanbjones opened this issue · 0 comments
ryanbjones commented
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 use
d, 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