代码之家  ›  专栏  ›  技术社区  ›  Ciro Santilli OurBigBook.com

当状态为引发异常的错误(如400)时,如何读取pythonurllib上的响应体?

  •  3
  • Ciro Santilli OurBigBook.com  · 技术社区  · 6 年前

    urllib 创建一个版本,但我犯了一些错误,它失败了一个例外:

    Traceback (most recent call last):
      File "./a.py", line 27, in <module>
        'Authorization': 'token ' + token,
      File "/usr/lib/python3.6/urllib/request.py", line 223, in urlopen
        return opener.open(url, data, timeout)
      File "/usr/lib/python3.6/urllib/request.py", line 532, in open
        response = meth(req, response)
      File "/usr/lib/python3.6/urllib/request.py", line 642, in http_response
        'http', request, response, code, msg, hdrs)
      File "/usr/lib/python3.6/urllib/request.py", line 570, in error
        return self._call_chain(*args)
      File "/usr/lib/python3.6/urllib/request.py", line 504, in _call_chain
        result = func(*args)
      File "/usr/lib/python3.6/urllib/request.py", line 650, in http_error_default
        raise HTTPError(req.full_url, code, msg, hdrs, fp)
    urllib.error.HTTPError: HTTP Error 422: Unprocessable Entity
    

    不过,GitHub很不错,它解释了为什么在响应主体上失败,如所示: 400 vs 422 response to POST of data

    那么,我该如何解读回应体呢?有没有办法防止引发异常?

    我尝试捕捉异常并在中进行探索 ipdb ,它给出了一个类型为 urllib.error.HTTPError 但我在那里找不到尸体数据,只有头。

    剧本:

    #!/usr/bin/env python3
    
    import json
    import os
    import sys
    
    from urllib.parse import urlencode
    from urllib.request import Request, urlopen
    
    repo = sys.argv[1]
    tag = sys.argv[2]
    upload_file = sys.argv[3]
    
    token = os.environ['GITHUB_TOKEN']
    url_template = 'https://{}.github.com/repos/' + repo + '/releases'
    
    # Create.
    _json = json.loads(urlopen(Request(
        url_template.format('api'),
        json.dumps({
            'tag_namezxcvxzcv': tag,
            'name': tag,
            'prerelease': True,
        }).encode(),
        headers={
            'Accept': 'application/vnd.github.v3+json',
            'Authorization': 'token ' + token,
        },
    )).read().decode())
    # This is not the tag, but rather some database integer identifier.
    release_id = _json['id']
    

    用法: Can someone give a python requests example of uploading a release asset in github?

    1 回复  |  直到 6 年前
        1
  •  20
  •   Will Keeling    5 年前

    这个 HTTPError 有一个 read() 方法,该方法允许您读取响应主体。因此,在您的情况下,您应该能够做一些事情,例如:

    try:
        body = urlopen(Request(
            url_template.format('api'),
            json.dumps({
                'tag_namezxcvxzcv': tag,
                'name': tag,
                'prerelease': True,
            }).encode(),
            headers={
                'Accept': 'application/vnd.github.v3+json',
                'Authorization': 'token ' + token,
            },
        )).read().decode()
    except urllib.error.HTTPError as e:
        body = e.read().decode()  # Read the body of the error response
    
    _json = json.loads(body)
    

    The docs HTTPError错误