首页 > 解决方案 > Heroku Flask 应用程序中的 json.decoder.JSONDecodeError - 如何调试?

问题描述

我已经构建了一个 Heroku 烧瓶应用程序,它连接到 Dynamics 365 的 Web API。我的应用程序时不时地崩溃并出现以下错误(从 Heroku 日志中复制粘贴):

2021-03-09T12:08:51.463416+00:00 heroku[router]: at=info method=GET path="/" host=holmed.herokuapp.com request_id=16a135a9-7b41-4813-944d-f616551b4875 fwd="89.64.66.42" dyno=web.1 connect=1ms service=156ms status=500 bytes=385 protocol=https
2021-03-09T12:08:51.461297+00:00 app[web.1]: [2021-03-09 12:08:51,460] ERROR in app: Exception on / [GET]
2021-03-09T12:08:51.461320+00:00 app[web.1]: Traceback (most recent call last):
2021-03-09T12:08:51.461321+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 2447, in wsgi_app
2021-03-09T12:08:51.461322+00:00 app[web.1]:     response = self.full_dispatch_request()
2021-03-09T12:08:51.461323+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1952, in full_dispatch_request
2021-03-09T12:08:51.461324+00:00 app[web.1]:     rv = self.handle_user_exception(e)
2021-03-09T12:08:51.461324+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1821, in handle_user_exception
2021-03-09T12:08:51.461324+00:00 app[web.1]:     reraise(exc_type, exc_value, tb)
2021-03-09T12:08:51.461325+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
2021-03-09T12:08:51.461326+00:00 app[web.1]:     raise value
2021-03-09T12:08:51.461326+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1950, in full_dispatch_request
2021-03-09T12:08:51.461327+00:00 app[web.1]:     rv = self.dispatch_request()
2021-03-09T12:08:51.461327+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1936, in dispatch_request
2021-03-09T12:08:51.461327+00:00 app[web.1]:     return self.view_functions[rule.endpoint](**req.view_args)
2021-03-09T12:08:51.461328+00:00 app[web.1]:   File "/app/app.py", line 222, in index
2021-03-09T12:08:51.461328+00:00 app[web.1]:     qualif = qualifications()[1]
2021-03-09T12:08:51.461329+00:00 app[web.1]:   File "/app/query.py", line 877, in qualifications
2021-03-09T12:08:51.461329+00:00 app[web.1]:     df = json_normalize(crmres.json()["value"])
2021-03-09T12:08:51.461330+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/requests/models.py", line 898, in json
2021-03-09T12:08:51.461330+00:00 app[web.1]:     return complexjson.loads(self.text, **kwargs)
2021-03-09T12:08:51.461331+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/json/__init__.py", line 354, in loads
2021-03-09T12:08:51.461332+00:00 app[web.1]:     return _default_decoder.decode(s)
2021-03-09T12:08:51.461332+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/json/decoder.py", line 339, in decode
2021-03-09T12:08:51.461332+00:00 app[web.1]:     obj, end = self.raw_decode(s, idx=_w(s, 0).end())
2021-03-09T12:08:51.461333+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/json/decoder.py", line 357, in raw_decode
2021-03-09T12:08:51.461333+00:00 app[web.1]:     raise JSONDecodeError("Expecting value", s, err.value) from None
2021-03-09T12:08:51.461340+00:00 app[web.1]: json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
2021-03-09T12:08:51.462396+00:00 app[web.1]: 10.12.107.73 - - [09/Mar/2021:12:08:51 +0000] "GET / HTTP/1.1" 500 205 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36"

这是我处理与 API 通信的代码

tokentype, token = get_access_token()
bearer = f'{tokentype} {token}'
DATA_URL = f"https://holmed.crm4.dynamics.com/data/"
crm_web_api = 'https://holmed.api.crm4.dynamics.com/api/data/v9.1'  # full path to web api endpoint

crm_request_headers = {
    'Authorization': bearer,
    'OData-MaxVersion': '4.0',
    'OData-Version': '4.0',
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=utf-8',
    'Prefer': 'odata.maxpagesize=500',
    'Prefer': 'odata.include-annotations=OData.Community.Display.V1.FormattedValue'
}

def crm_read(query_string):
    return requests.get(crm_web_api + query_string, headers=crm_request_headers)

def qualifications():
    query_string = "/is_potentialpatients?$filter=statuscode%20eq%20100000001"
    crmres = crm_read(query_string)
    df = json_normalize(crmres.json()["value"]) # THE ERROR HAPPENS OVER HERE
    if df.empty:
        html = "Brak oczekujących na kwalifikacje."
        qualif = 0
    else:
        try:
            df = df[['is_name', 'is_phonenumber', 'is_comments', 'is_hospital@OData.Community.Display.V1.FormattedValue',
                 'is_referral_date']]
            df = df.rename(columns={'is_name': 'Nazwisko', 'is_phonenumber': 'Numer telefonu', 'is_comments': 'Uwagi',
                                'is_hospital@OData.Community.Display.V1.FormattedValue': 'Szpital kierujący',
                                'is_referral_date': 'Data ze skierowania'})
        except KeyError:
            df = df[['is_name', 'is_phonenumber', 'is_comments',
                 'is_referral_date']]
            df = df.rename(columns={'is_name': 'Nazwisko', 'is_phonenumber': 'Numer telefonu', 'is_comments': 'Uwagi','is_referral_date': 'Data ze skierowania'})

        df['Data ze skierowania'] = df['Data ze skierowania'].str.slice(start=0, stop=10)
        qualif = df['Nazwisko'].count()
        df = df.fillna("")
        html = df.to_html()
        html = html.replace("dataframe", "table table-hover table-sm")
        html = html.replace("None", "")
    return html, qualif

qualif = qualifications()[1]
print(qualif)

我用于 API 调用的 URL 在浏览器中运行良好。当我从 IDE 执行它时,我的 python 代码运行良好。当我在 Heroku 上重新构建我的应用程序时,它再次开始工作,只是在几天后抛出上述错误后崩溃。

我已经查看了有关堆栈溢出的所有相关问题,但没有一个特别关注 heroku,而且我找不到任何解决该问题的方法。

有什么想法吗?

编辑:我被要求提供“调试细节”。我试图通过从我的 IDE 运行上述代码来重现此错误。但是,代码运行良好。因此,我不确定我可以进一步提供哪些调试细节......你将如何调试这个?:-)

标签: pythonjsonherokupython-requests

解决方案


为了调试问题,您需要改进应用程序日志记录。我将进行以下更改以调试问题:

def crm_read(query_string):
    print(crm_web_api + query_string)
    response = requests.get(crm_web_api + query_string, headers=crm_request_headers)
    print(response.status_code)
    return response

def qualifications():
    query_string = "/is_potentialpatients?$filter=statuscode%20eq%20100000001"
    crmres = crm_read(query_string)
    print(crmres.json())
    df = json_normalize(crmres.json()["value"]) # THE ERROR HAPPENS OVER HERE

如果您使用的是 Flask,只需将print语句替换为app.logger.info并相应地降低应用程序日志记录级别。这应该允许您调试您的应用程序在生产中发生的情况。


推荐阅读