Repository: elastic/apm-agent-python

Issue:
occasionally raise Exception: too many values to unpack (expected 2) and 'NoneType' object is not iterable
**Describe the bug**:

occasionally raise Exception: too many values to unpack (expected 2) and 'NoneType' object is not iterable

![image](https://user-images.githubusercontent.com/37948697/102018341-a90d8380-3da7-11eb-9f5d-f88dfa5b00fe.png)

![image](https://user-images.githubusercontent.com/37948697/102018489-7a43dd00-3da8-11eb-99c6-d41eaa91d0c9.png)


**To Reproduce**

can not reproduce, it happen occasionally

**Environment (please complete the following information)**
- OS: Ubuntu 28.04
- Python version: 3.7.5
- Framework and version: flask 1.1.1 flask-sqlalchemy	2.3.2

- Agent version: 5.8.1


- Agent config options <!-- be careful not to post sensitive information -->
  <details>
    <summary>Click to expand</summary>

    ```
        ELASTIC_APM = {
            "SERVICE_NAME": f"we-work-server_{RUN_ENV}",
            "SERVER_URL": "",
            "ENABLED": True,
            "DISABLE_SEND: False,
            "RECORDING": True,
            "INSTRUMENT": True,
            "ENABLE_DISTRIBUTED_TRACING": True,
            "USE_ELASTIC_TRACEPARENT_HEADER": True,
            "CLOUD_PROVIDER": False,
            "INSTRUMENT_DJANGO_MIDDLEWARE": False,
            "AUTOINSERT_DJANGO_MIDDLEWARE": False,
            "SERVICE_VERSION": os.getenv("CODE_RELEASE_VERSION", None),
    }
    ```
  </details>
- `requirements.txt`:
  <details>
    <summary>Click to expand</summary>

    ```
        attrs==19.3.0
        celery==4.4.6
        certifi==2019.11.28
        cffi==1.13.2
        chardet==3.0.4
        crcmod==1.7
        cryptography==2.8
        flasgger==0.9.3
        Flask==1.1.1
        Flask-Redis==0.3.0
        Flask-SQLAlchemy==2.3.2
        greenlet==0.4.14
        idna==2.8
        importlib-metadata==1.2.0
        itsdangerous==1.1.0
        Jinja2==2.10.3
        jmespath==0.9.4
        jsonschema==2.6.0
        lxml==4.4.1
        MarkupSafe==1.1.1
        mistune==0.8.4
        more-itertools==8.0.1
        pybase64==1.0.1
        pycodestyle==2.5.0
        pycparser==2.19
        pycryptodome==3.8.2
        PyMySQL==0.8.1
        pyrsistent==0.15.6
        pytz==2019.3
        PyYAML==5.1.2
        redis==3.3.11
        six==1.13.0
        specs==0.0.0
        SQLAlchemy==1.2.8
        typing-extensions==3.7.4.1
        urllib3==1.25.7
        uWSGI==2.0.18
        vine==1.3.0
        Werkzeug==0.16.0
        xmltodict==0.11.0
        zipp==0.6.0
        xlrd==1.2.0
        pyzbar==0.1.8
        Pillow==7.1.1
        urlextract==0.14.0
        elastic-apm==5.8.1
        sentry-sdk[flask]==0.15.1
        arrow==0.16.0
        sqlparse==0.3.1
        elasticsearch==7.9.1
        pydantic==1.6.1
        apispec==3.3.2
        marshmallow==3.7.1
        python-socketio==4.6.0
    ```
  </details>



Discussion:
Apologies for our late reply here. The holidays and all that. I'm going to take a look at this.
@wangjiancn I think I've tracked down the source of the `'NoneType' object is not iterable` errors.

Can you show me the rest of the stack trace from the `ValueError: too many values to unpack` please? It's very helpful to see the calling code path so I can see where the weird values may be coming from. The second screenshot has those additional lines of context in the bottom third, that's what I'm looking for from the first screenshot.

Resolving patch:
diff --git a/elasticapm/traces.py b/elasticapm/traces.py
--- a/elasticapm/traces.py
+++ b/elasticapm/traces.py
@@ -467,7 +467,7 @@ def end(self, skip_frames=0, duration=None):
         tracer = self.transaction.tracer
         timestamp = _time_func()
         self.duration = duration if duration is not None else (timestamp - self.start_time)
-        if not tracer.span_frames_min_duration or self.duration >= tracer.span_frames_min_duration:
+        if not tracer.span_frames_min_duration or self.duration >= tracer.span_frames_min_duration and self.frames:
             self.frames = tracer.frames_processing_func(self.frames)[skip_frames:]
         else:
             self.frames = None


Test patch: