prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Jaeger Propagator not handling missing carrier
  Python 3.8 / Flask injector 0.17b0
  
  
  **Steps to reproduce**
  If jaeger is the text map and you do not send a carrier header then the parser fails when it tries to parse the carrier header.
  
  ```python
          if context is None:
              context = get_current()
          fields = _extract_first_element(
              getter.get(carrier, self.TRACE_ID_KEY)
          ).split(":")
  ```
  
  **What is the expected **
  Parse as invalid span. Code continues.
  
  **What is the actual behavior?**
  ```
  File "/usr/local/lib/python3.8/site-packages/opentelemetry/propagators/jaeger/__init__.py", line 48, in extract
   fields = _extract_first_element(
  AttributeError: 'NoneType' object has no attribute ‘split’
  ```
  
  **Additional context**
  TraceContextTextMapPropagator does this:
  
  ```python
          header = getter.get(carrier, self._TRACEPARENT_HEADER_NAME)
  
          if not header:
              return trace.set_span_in_context(trace.INVALID_SPAN, context)
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py`
  Content:
  ```
  1 # Copyright The OpenTelemetry Authors
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 #     http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 
  15 import typing
  16 import urllib.parse
  17 
  18 import opentelemetry.trace as trace
  19 from opentelemetry import baggage
  20 from opentelemetry.context import Context, get_current
  21 from opentelemetry.trace.propagation.textmap import (
  22     Getter,
  23     Setter,
  24     TextMapPropagator,
  25     TextMapPropagatorT,
  26 )
  27 
  28 
  29 class JaegerPropagator(TextMapPropagator):
  30     """Propagator for the Jaeger format.
  31 
  32     See: https://www.jaegertracing.io/docs/1.19/client-libraries/#propagation-format
  33     """
  34 
  35     TRACE_ID_KEY = "uber-trace-id"
  36     BAGGAGE_PREFIX = "uberctx-"
  37     DEBUG_FLAG = 0x02
  38 
  39     def extract(
  40         self,
  41         getter: Getter[TextMapPropagatorT],
  42         carrier: TextMapPropagatorT,
  43         context: typing.Optional[Context] = None,
  44     ) -> Context:
  45 
  46         if context is None:
  47             context = get_current()
  48         fields = _extract_first_element(
  49             getter.get(carrier, self.TRACE_ID_KEY)
  50         ).split(":")
  51 
  52         context = self._extract_baggage(getter, carrier, context)
  53         if len(fields) != 4:
  54             return trace.set_span_in_context(trace.INVALID_SPAN, context)
  55 
  56         trace_id, span_id, _parent_id, flags = fields
  57         if (
  58             trace_id == trace.INVALID_TRACE_ID
  59             or span_id == trace.INVALID_SPAN_ID
  60         ):
  61             return trace.set_span_in_context(trace.INVALID_SPAN, context)
  62 
  63         span = trace.DefaultSpan(
  64             trace.SpanContext(
  65                 trace_id=int(trace_id, 16),
  66                 span_id=int(span_id, 16),
  67                 is_remote=True,
  68                 trace_flags=trace.TraceFlags(
  69                     int(flags, 16) & trace.TraceFlags.SAMPLED
  70                 ),
  71             )
  72         )
  73         return trace.set_span_in_context(span, context)
  74 
  75     def inject(
  76         self,
  77         set_in_carrier: Setter[TextMapPropagatorT],
  78         carrier: TextMapPropagatorT,
  79         context: typing.Optional[Context] = None,
  80     ) -> None:
  81         span = trace.get_current_span(context=context)
  82         span_context = span.get_span_context()
  83         if span_context == trace.INVALID_SPAN_CONTEXT:
  84             return
  85 
  86         span_parent_id = span.parent.span_id if span.parent else 0
  87         trace_flags = span_context.trace_flags
  88         if trace_flags.sampled:
  89             trace_flags |= self.DEBUG_FLAG
  90 
  91         # set span identity
  92         set_in_carrier(
  93             carrier,
  94             self.TRACE_ID_KEY,
  95             _format_uber_trace_id(
  96                 span_context.trace_id,
  97                 span_context.span_id,
  98                 span_parent_id,
  99                 trace_flags,
  100             ),
  101         )
  102 
  103         # set span baggage, if any
  104         baggage_entries = baggage.get_all(context=context)
  105         if not baggage_entries:
  106             return
  107         for key, value in baggage_entries.items():
  108             baggage_key = self.BAGGAGE_PREFIX + key
  109             set_in_carrier(
  110                 carrier, baggage_key, urllib.parse.quote(str(value))
  111             )
  112 
  113     @property
  114     def fields(self) -> typing.Set[str]:
  115         return {self.TRACE_ID_KEY}
  116 
  117     def _extract_baggage(self, getter, carrier, context):
  118         baggage_keys = [
  119             key
  120             for key in getter.keys(carrier)
  121             if key.startswith(self.BAGGAGE_PREFIX)
  122         ]
  123         for key in baggage_keys:
  124             value = _extract_first_element(getter.get(carrier, key))
  125             context = baggage.set_baggage(
  126                 key.replace(self.BAGGAGE_PREFIX, ""),
  127                 urllib.parse.unquote(value).strip(),
  128                 context=context,
  129             )
  130         return context
  131 
  132 
  133 def _format_uber_trace_id(trace_id, span_id, parent_span_id, flags):
  134     return "{:032x}:{:016x}:{:016x}:{:02x}".format(
  135         trace_id, span_id, parent_span_id, flags
  136     )
  137 
  138 
  139 def _extract_first_element(
  140     items: typing.Iterable[TextMapPropagatorT],
  141 ) -> typing.Optional[TextMapPropagatorT]:
  142     if items is None:
  143         return None
  144     return next(iter(items), None)
  145
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py b/propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py
  --- a/propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py
  +++ b/propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py
  @@ -45,9 +45,10 @@
   
           if context is None:
               context = get_current()
  -        fields = _extract_first_element(
  -            getter.get(carrier, self.TRACE_ID_KEY)
  -        ).split(":")
  +        header = getter.get(carrier, self.TRACE_ID_KEY)
  +        if not header:
  +            return trace.set_span_in_context(trace.INVALID_SPAN, context)
  +        fields = _extract_first_element(header).split(":")
   
           context = self._extract_baggage(getter, carrier, context)
           if len(fields) != 4:
  
verification_info: {"golden_diff": "diff --git a/propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py b/propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py\n--- a/propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py\n+++ b/propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py\n@@ -45,9 +45,10 @@\n \n         if context is None:\n             context = get_current()\n-        fields = _extract_first_element(\n-            getter.get(carrier, self.TRACE_ID_KEY)\n-        ).split(\":\")\n+        header = getter.get(carrier, self.TRACE_ID_KEY)\n+        if not header:\n+            return trace.set_span_in_context(trace.INVALID_SPAN, context)\n+        fields = _extract_first_element(header).split(\":\")\n \n         context = self._extract_baggage(getter, carrier, context)\n         if len(fields) != 4:\n", "issue": "Jaeger Propagator not handling missing carrier\nPython 3.8 / Flask injector 0.17b0\r\n\r\n\r\n**Steps to reproduce**\r\nIf jaeger is the text map and you do not send a carrier header then the parser fails when it tries to parse the carrier header.\r\n\r\n```python\r\n        if context is None:\r\n            context = get_current()\r\n        fields = _extract_first_element(\r\n            getter.get(carrier, self.TRACE_ID_KEY)\r\n        ).split(\":\")\r\n```\r\n\r\n**What is the expected **\r\nParse as invalid span. Code continues.\r\n\r\n**What is the actual behavior?**\r\n```\r\nFile \"/usr/local/lib/python3.8/site-packages/opentelemetry/propagators/jaeger/__init__.py\", line 48, in extract\r\n fields = _extract_first_element(\r\nAttributeError: 'NoneType' object has no attribute \u2018split\u2019\r\n```\r\n\r\n**Additional context**\r\nTraceContextTextMapPropagator does this:\r\n\r\n```python\r\n        header = getter.get(carrier, self._TRACEPARENT_HEADER_NAME)\r\n\r\n        if not header:\r\n            return trace.set_span_in_context(trace.INVALID_SPAN, context)\r\n```\n", "before_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport typing\nimport urllib.parse\n\nimport opentelemetry.trace as trace\nfrom opentelemetry import baggage\nfrom opentelemetry.context import Context, get_current\nfrom opentelemetry.trace.propagation.textmap import (\n    Getter,\n    Setter,\n    TextMapPropagator,\n    TextMapPropagatorT,\n)\n\n\nclass JaegerPropagator(TextMapPropagator):\n    \"\"\"Propagator for the Jaeger format.\n\n    See: https://www.jaegertracing.io/docs/1.19/client-libraries/#propagation-format\n    \"\"\"\n\n    TRACE_ID_KEY = \"uber-trace-id\"\n    BAGGAGE_PREFIX = \"uberctx-\"\n    DEBUG_FLAG = 0x02\n\n    def extract(\n        self,\n        getter: Getter[TextMapPropagatorT],\n        carrier: TextMapPropagatorT,\n        context: typing.Optional[Context] = None,\n    ) -> Context:\n\n        if context is None:\n            context = get_current()\n        fields = _extract_first_element(\n            getter.get(carrier, self.TRACE_ID_KEY)\n        ).split(\":\")\n\n        context = self._extract_baggage(getter, carrier, context)\n        if len(fields) != 4:\n            return trace.set_span_in_context(trace.INVALID_SPAN, context)\n\n        trace_id, span_id, _parent_id, flags = fields\n        if (\n            trace_id == trace.INVALID_TRACE_ID\n            or span_id == trace.INVALID_SPAN_ID\n        ):\n            return trace.set_span_in_context(trace.INVALID_SPAN, context)\n\n        span = trace.DefaultSpan(\n            trace.SpanContext(\n                trace_id=int(trace_id, 16),\n                span_id=int(span_id, 16),\n                is_remote=True,\n                trace_flags=trace.TraceFlags(\n                    int(flags, 16) & trace.TraceFlags.SAMPLED\n                ),\n            )\n        )\n        return trace.set_span_in_context(span, context)\n\n    def inject(\n        self,\n        set_in_carrier: Setter[TextMapPropagatorT],\n        carrier: TextMapPropagatorT,\n        context: typing.Optional[Context] = None,\n    ) -> None:\n        span = trace.get_current_span(context=context)\n        span_context = span.get_span_context()\n        if span_context == trace.INVALID_SPAN_CONTEXT:\n            return\n\n        span_parent_id = span.parent.span_id if span.parent else 0\n        trace_flags = span_context.trace_flags\n        if trace_flags.sampled:\n            trace_flags |= self.DEBUG_FLAG\n\n        # set span identity\n        set_in_carrier(\n            carrier,\n            self.TRACE_ID_KEY,\n            _format_uber_trace_id(\n                span_context.trace_id,\n                span_context.span_id,\n                span_parent_id,\n                trace_flags,\n            ),\n        )\n\n        # set span baggage, if any\n        baggage_entries = baggage.get_all(context=context)\n        if not baggage_entries:\n            return\n        for key, value in baggage_entries.items():\n            baggage_key = self.BAGGAGE_PREFIX + key\n            set_in_carrier(\n                carrier, baggage_key, urllib.parse.quote(str(value))\n            )\n\n    @property\n    def fields(self) -> typing.Set[str]:\n        return {self.TRACE_ID_KEY}\n\n    def _extract_baggage(self, getter, carrier, context):\n        baggage_keys = [\n            key\n            for key in getter.keys(carrier)\n            if key.startswith(self.BAGGAGE_PREFIX)\n        ]\n        for key in baggage_keys:\n            value = _extract_first_element(getter.get(carrier, key))\n            context = baggage.set_baggage(\n                key.replace(self.BAGGAGE_PREFIX, \"\"),\n                urllib.parse.unquote(value).strip(),\n                context=context,\n            )\n        return context\n\n\ndef _format_uber_trace_id(trace_id, span_id, parent_span_id, flags):\n    return \"{:032x}:{:016x}:{:016x}:{:02x}\".format(\n        trace_id, span_id, parent_span_id, flags\n    )\n\n\ndef _extract_first_element(\n    items: typing.Iterable[TextMapPropagatorT],\n) -> typing.Optional[TextMapPropagatorT]:\n    if items is None:\n        return None\n    return next(iter(items), None)\n", "path": "propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py"}], "after_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport typing\nimport urllib.parse\n\nimport opentelemetry.trace as trace\nfrom opentelemetry import baggage\nfrom opentelemetry.context import Context, get_current\nfrom opentelemetry.trace.propagation.textmap import (\n    Getter,\n    Setter,\n    TextMapPropagator,\n    TextMapPropagatorT,\n)\n\n\nclass JaegerPropagator(TextMapPropagator):\n    \"\"\"Propagator for the Jaeger format.\n\n    See: https://www.jaegertracing.io/docs/1.19/client-libraries/#propagation-format\n    \"\"\"\n\n    TRACE_ID_KEY = \"uber-trace-id\"\n    BAGGAGE_PREFIX = \"uberctx-\"\n    DEBUG_FLAG = 0x02\n\n    def extract(\n        self,\n        getter: Getter[TextMapPropagatorT],\n        carrier: TextMapPropagatorT,\n        context: typing.Optional[Context] = None,\n    ) -> Context:\n\n        if context is None:\n            context = get_current()\n        header = getter.get(carrier, self.TRACE_ID_KEY)\n        if not header:\n            return trace.set_span_in_context(trace.INVALID_SPAN, context)\n        fields = _extract_first_element(header).split(\":\")\n\n        context = self._extract_baggage(getter, carrier, context)\n        if len(fields) != 4:\n            return trace.set_span_in_context(trace.INVALID_SPAN, context)\n\n        trace_id, span_id, _parent_id, flags = fields\n        if (\n            trace_id == trace.INVALID_TRACE_ID\n            or span_id == trace.INVALID_SPAN_ID\n        ):\n            return trace.set_span_in_context(trace.INVALID_SPAN, context)\n\n        span = trace.DefaultSpan(\n            trace.SpanContext(\n                trace_id=int(trace_id, 16),\n                span_id=int(span_id, 16),\n                is_remote=True,\n                trace_flags=trace.TraceFlags(\n                    int(flags, 16) & trace.TraceFlags.SAMPLED\n                ),\n            )\n        )\n        return trace.set_span_in_context(span, context)\n\n    def inject(\n        self,\n        set_in_carrier: Setter[TextMapPropagatorT],\n        carrier: TextMapPropagatorT,\n        context: typing.Optional[Context] = None,\n    ) -> None:\n        span = trace.get_current_span(context=context)\n        span_context = span.get_span_context()\n        if span_context == trace.INVALID_SPAN_CONTEXT:\n            return\n\n        span_parent_id = span.parent.span_id if span.parent else 0\n        trace_flags = span_context.trace_flags\n        if trace_flags.sampled:\n            trace_flags |= self.DEBUG_FLAG\n\n        # set span identity\n        set_in_carrier(\n            carrier,\n            self.TRACE_ID_KEY,\n            _format_uber_trace_id(\n                span_context.trace_id,\n                span_context.span_id,\n                span_parent_id,\n                trace_flags,\n            ),\n        )\n\n        # set span baggage, if any\n        baggage_entries = baggage.get_all(context=context)\n        if not baggage_entries:\n            return\n        for key, value in baggage_entries.items():\n            baggage_key = self.BAGGAGE_PREFIX + key\n            set_in_carrier(\n                carrier, baggage_key, urllib.parse.quote(str(value))\n            )\n\n    @property\n    def fields(self) -> typing.Set[str]:\n        return {self.TRACE_ID_KEY}\n\n    def _extract_baggage(self, getter, carrier, context):\n        baggage_keys = [\n            key\n            for key in getter.keys(carrier)\n            if key.startswith(self.BAGGAGE_PREFIX)\n        ]\n        for key in baggage_keys:\n            value = _extract_first_element(getter.get(carrier, key))\n            context = baggage.set_baggage(\n                key.replace(self.BAGGAGE_PREFIX, \"\"),\n                urllib.parse.unquote(value).strip(),\n                context=context,\n            )\n        return context\n\n\ndef _format_uber_trace_id(trace_id, span_id, parent_span_id, flags):\n    return \"{:032x}:{:016x}:{:016x}:{:02x}\".format(\n        trace_id, span_id, parent_span_id, flags\n    )\n\n\ndef _extract_first_element(\n    items: typing.Iterable[TextMapPropagatorT],\n) -> typing.Optional[TextMapPropagatorT]:\n    if items is None:\n        return None\n    return next(iter(items), None)\n", "path": "propagator/opentelemetry-propagator-jaeger/src/opentelemetry/propagators/jaeger/__init__.py"}]}