Skip to content

Commit

Permalink
changes with_span to use start/end span
Browse files Browse the repository at this point in the history
previously dyalizer would not error on invalid contracts for functions
annotated with the decorator. presumably this was because the return
actually happens in a closure.

So, for example, the following code would pass dialyzer successfully

```elixir
@SPEC hello :: {:ok, :asdf}
@decorate with_span("hello")
def hello do
  :world
end
````

After this change it fails as expected

```
lib/spec_demo.ex:17:invalid_contract
The @SPEC for the function does not match the success typing of the function.

Function:
SpecDemo.hello/0

Success typing:
@SPEC hello() :: :world
```
  • Loading branch information
marcdel committed Dec 13, 2023
1 parent 01373df commit 4ef11a0
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 31 deletions.
56 changes: 29 additions & 27 deletions lib/open_telemetry_decorator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -46,36 +46,38 @@ defmodule OpenTelemetryDecorator do
require OpenTelemetry.Tracer, as: Tracer
require OpenTelemetry.Span, as: Span

Tracer.with_span unquote(span_name) do
span_context = Tracer.current_span_ctx()
span = Tracer.start_span(unquote(span_name))
Tracer.set_current_span(span)

input_params =
input_params =
Kernel.binding()
|> Attributes.get(unquote(include))
|> Keyword.delete(:result)

Attributes.set(input_params)

try do
result = unquote(body)

attrs =
Kernel.binding()
|> Keyword.put(:result, result)
|> Attributes.get(unquote(include))
|> Keyword.delete(:result)

Attributes.set(input_params)

try do
result = unquote(body)

attrs =
Kernel.binding()
|> Keyword.put(:result, result)
|> Attributes.get(unquote(include))
|> Keyword.merge(input_params)
|> Enum.map(fn {k, v} -> {Atom.to_string(k), v} end)

# Called functions can mess up Tracer's current span context, so ensure we at least write to ours
Attributes.set(span_context, attrs)

result
rescue
e ->
Tracer.record_exception(e)
Tracer.set_status(OpenTelemetry.status(:error))
reraise e, __STACKTRACE__
end
|> Keyword.merge(input_params)
|> Enum.map(fn {k, v} -> {Atom.to_string(k), v} end)

# Called functions can mess up Tracer's current span context, so ensure we at least write to ours
Attributes.set(span, attrs)
Span.end_span(span)

result
rescue
e ->
Tracer.record_exception(e)
Tracer.set_status(OpenTelemetry.status(:error))
Span.end_span(span)

reraise e, __STACKTRACE__
end
end
rescue
Expand Down
2 changes: 1 addition & 1 deletion test/open_telemetry_decorator/attributes_v1_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule OpenTelemetryDecorator.AttributesV1Test do
use ExUnit.Case, async: true
use ExUnit.Case, async: false
use OtelHelper

alias OpenTelemetryDecorator.AttributesV1, as: Attributes
Expand Down
2 changes: 1 addition & 1 deletion test/open_telemetry_decorator/attributes_v2_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule OpenTelemetryDecorator.AttributesV2Test do
use ExUnit.Case, async: true
use ExUnit.Case, async: false
use OtelHelper

alias OpenTelemetryDecorator.AttributesV2, as: Attributes
Expand Down
2 changes: 1 addition & 1 deletion test/open_telemetry_decorator/validator_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule OpenTelemetryDecorator.ValidatorTest do
use ExUnit.Case, async: true
use ExUnit.Case, async: false

alias OpenTelemetryDecorator.Validator

Expand Down
2 changes: 1 addition & 1 deletion test/open_telemetry_decorator_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule OpenTelemetryDecoratorTest do
use ExUnit.Case, async: true
use ExUnit.Case, async: false
use OtelHelper

doctest OpenTelemetryDecorator
Expand Down

0 comments on commit 4ef11a0

Please sign in to comment.