# Buggy code
def get_data_from_request(request, capture_body=False):
    result = {
        "env": dict(get_environ(request.environ)),
        "headers": dict(get_headers(request.environ)),
        "method": request.method,
        "socket": {
            "remote_address": request.environ.get("REMOTE_ADDR"),
            "encrypted": request.is_secure,
        },
        "cookies": request.cookies,
    }
    if request.method in constants.HTTP_WITH_BODY:
        body = None
        if request.content_type == "application/x-www-form-urlencoded":
            body = compat.multidict_to_dict(request.form)
        elif request.content_type and request.content_type.startswith(
            "multipart/form-data"
        ):
            body = compat.multidict_to_dict(request.form)
            if request.files:
                body["_files"] = {
                    field: val[0].filename
                    if len(val) == 1
                    else [f.filename for f in val]
                    for field, val in compat.iterlists(request.files)
                }
        else:
            try:
                body = request.data
            except ClientDisconnected:
                pass

        if body is not None:
            result["body"] = body if capture_body else "[REDACTED]"

    result["url"] = get_url_dict(request.url)
    return result


# Traceback (flask_api.exceptions.ParseError)
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1816, in full_dispatch_request
return self.finalize_request(rv)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1834, in finalize_request
request_finished.send(self, response=response)
File "/usr/local/lib/python3.6/site-packages/blinker/base.py", line 267, in send
for receiver in self.receivers_for(sender)]
File "/usr/local/lib/python3.6/site-packages/blinker/base.py", line 267, in <listcomp>
for receiver in self.receivers_for(sender)]
File "/usr/local/lib/python3.6/site-packages/elasticapm/contrib/flask/__init__.py", line 145, in request_finished
"request",
File "/usr/local/lib/python3.6/site-packages/elasticapm/traces.py", line 333, in set_context
data = data()
File "/usr/local/lib/python3.6/site-packages/elasticapm/contrib/flask/__init__.py", line 143, in <lambda>
request, capture_body=self.client.config.capture_body in ("transactions", "all")
File "/usr/local/lib/python3.6/site-packages/elasticapm/contrib/flask/utils.py", line 29, in get_data_from_request
body = request.data
File "/usr/local/lib/python3.6/site-packages/werkzeug/local.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
File "/usr/local/lib/python3.6/site-packages/flask_api/request.py", line 24, in data
self._parse()
File "/usr/local/lib/python3.6/site-packages/flask_api/request.py", line 53, in _parse
ret = parser.parse(self.stream, media_type, **options)
File "/usr/local/lib/python3.6/site-packages/flask_api/parsers.py", line 32, in parse
raise exceptions.ParseError(msg)
flask_api.exceptions.ParseError: JSON parse error - Expecting value: line 1 column 1 (char 0)

# Fixed code
def get_data_from_request(request, capture_body=False):
    result = {
        "env": dict(get_environ(request.environ)),
        "headers": dict(get_headers(request.environ)),
        "method": request.method,
        "socket": {
            "remote_address": request.environ.get("REMOTE_ADDR"),
            "encrypted": request.is_secure,
        },
        "cookies": request.cookies,
    }
    if request.method in constants.HTTP_WITH_BODY:
        body = None
        if request.content_type == "application/x-www-form-urlencoded":
            body = compat.multidict_to_dict(request.form)
        elif request.content_type and request.content_type.startswith(
            "multipart/form-data"
        ):
            body = compat.multidict_to_dict(request.form)
            if request.files:
                body["_files"] = {
                    field: val[0].filename
                    if len(val) == 1
                    else [f.filename for f in val]
                    for field, val in compat.iterlists(request.files)
                }
        else:
            try:
                body = request.get_data(as_text=True)
            except ClientDisconnected:
                pass

        if body is not None:
            result["body"] = body if capture_body else "[REDACTED]"

    result["url"] = get_url_dict(request.url)
    return result