Repository: open-telemetry/opentelemetry-ruby (Ruby)

Issue:
Jaeger Propagator: Extract doesn't handle missing trace id header
<!--

NOTE: Please use this form to submit bugs or demonstrations of non spec compliant behaviour

-->

**Description of the bug**

When using Rack Tracer Middleware with Jaeger propagator, if the app receives a request without an `uber-trace-id` in the header there is an exception:
```
[2022-03-27 13:04:08] ERROR NoMethodError: undefined method `match' for nil:NilClass
	/home/james/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/opentelemetry-propagator-jaeger-0.19.3/lib/opentelemetry/propagator/jaeger/text_map_propagator.rb:48:in `extract'
	/home/james/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/opentelemetry-instrumentation-rack-0.20.1/lib/opentelemetry/instrumentation/rack/middlewares/tracer_middleware.rb:69:in `call'
	/home/james/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/rack-2.2.3/lib/rack/handler/webrick.rb:95:in `service'
	/home/james/.rbenv/versions/2.5.0/lib/ruby/2.5.0/webrick/httpserver.rb:140:in `service'
	/home/james/.rbenv/versions/2.5.0/lib/ruby/2.5.0/webrick/httpserver.rb:96:in `run'
	/home/james/.rbenv/versions/2.5.0/lib/ruby/2.5.0/webrick/server.rb:307:in `block in start_thread'
```

**Share details about your runtime**

Operating system details: Linux, Ubuntu 20.04 LTS
RUBY_ENGINE: "ruby"
RUBY_VERSION: "2.5.0"
RUBY_DESCRIPTION: "ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]"

**Share a simplified reproduction if possible**

```rb
require 'bundler/inline'

gemfile(true) do
  source 'https://rubygems.org'

  gem 'opentelemetry-api'
  gem 'opentelemetry-sdk'
  gem 'opentelemetry-instrumentation-all'
  gem 'opentelemetry-exporter-jaeger'
  gem 'opentelemetry-propagator-jaeger'
  gem 'rack'

end

require 'opentelemetry-api'
require 'opentelemetry-sdk'
require 'opentelemetry/exporter/jaeger'
require 'opentelemetry-propagator-jaeger'
require 'rack'

OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ciphers]=OpenSSL::SSL::SSLContext.new.ciphers;

ENV['OTEL_TRACES_EXPORTER'] = 'jaeger'
ENV['OTEL_PROPAGATORS'] = 'jaeger'

OpenTelemetry::SDK.configure do |c|
  c.use_all
end

app = Rack::Builder.app do
  use OpenTelemetry::Instrumentation::Rack::Middlewares::TracerMiddleware
  run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
end
Rack::Server.start app: app, Port: 8080
```

Then run the following and view the logs:
```bash
curl localhost:8080
```





Discussion:

Patch:
diff --git a/propagator/jaeger/lib/opentelemetry/propagator/jaeger/text_map_propagator.rb b/propagator/jaeger/lib/opentelemetry/propagator/jaeger/text_map_propagator.rb
index 99f455afb1..06000417f2 100644
--- a/propagator/jaeger/lib/opentelemetry/propagator/jaeger/text_map_propagator.rb
+++ b/propagator/jaeger/lib/opentelemetry/propagator/jaeger/text_map_propagator.rb
@@ -45,6 +45,7 @@ class TextMapPropagator
         #   if extraction fails
         def extract(carrier, context: Context.current, getter: Context::Propagation.text_map_getter)
           header = getter.get(carrier, IDENTITY_KEY)
+          return context unless header
           return context unless (match = header.match(TRACE_SPAN_IDENTITY_REGEX))
           return context if match['trace_id'] =~ ZERO_ID_REGEX
           return context if match['span_id'] =~ ZERO_ID_REGEX


Test patch:
diff --git a/propagator/jaeger/test/text_map_propagator_test.rb b/propagator/jaeger/test/text_map_propagator_test.rb
index a89351c017..0f9320aba9 100644
--- a/propagator/jaeger/test/text_map_propagator_test.rb
+++ b/propagator/jaeger/test/text_map_propagator_test.rb
@@ -156,6 +156,13 @@ def extracted_context_must_equal_parent_context(header)
       )
       extracted_context_must_equal_parent_context('00:00:0:1')
     end
+
+    it 'handles missing trace context' do
+      parent_context = OpenTelemetry::Context.empty
+      carrier = {}
+      context = propagator.extract(carrier, context: parent_context)
+      _(context).must_equal(parent_context)
+    end
   end
 
   describe '#inject' do