Cách chính xác để thử / ngoại trừ sử dụng mô-đun yêu cầu Python?


Câu trả lời:


795

Có một cái nhìn vào các tài liệu ngoại lệ Yêu cầu . Nói ngắn gọn:

Trong trường hợp xảy ra sự cố mạng (ví dụ: lỗi DNS, kết nối bị từ chối, v.v.), Yêu cầu sẽ đưa ra một ConnectionErrorngoại lệ.

Trong trường hợp phản hồi HTTP không hợp lệ hiếm gặp, Yêu cầu sẽ đưa ra một HTTPErrorngoại lệ.

Nếu một yêu cầu hết thời gian, một Timeoutngoại lệ được đưa ra.

Nếu một yêu cầu vượt quá số lần chuyển hướng tối đa được định cấu hình, một TooManyRedirectsngoại lệ sẽ được đưa ra.

Tất cả các ngoại lệ mà Yêu cầu tăng rõ ràng kế thừa từ requests.exceptions.RequestException.

Để trả lời câu hỏi của bạn, những gì bạn thể hiện sẽ không bao gồm tất cả các cơ sở của bạn. Bạn sẽ chỉ bắt lỗi liên quan đến kết nối, không phải là lỗi đã hết.

Phải làm gì khi bạn bắt được ngoại lệ thực sự tùy thuộc vào thiết kế kịch bản / chương trình của bạn. Có thể chấp nhận để thoát? Bạn có thể tiếp tục và thử lại không? Nếu lỗi là thảm khốc và bạn không thể tiếp tục, thì có, bạn có thể hủy bỏ chương trình của mình bằng cách nâng SystemExit (một cách hay để vừa in lỗi và gọi sys.exit).

Bạn có thể bắt ngoại lệ lớp cơ sở, sẽ xử lý tất cả các trường hợp:

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.RequestException as e:  # This is the correct syntax
    raise SystemExit(e)

Hoặc bạn có thể bắt chúng một cách riêng biệt và làm những việc khác nhau.

try:
    r = requests.get(url, params={'s': thing})
except requests.exceptions.Timeout:
    # Maybe set up for a retry, or continue in a retry loop
except requests.exceptions.TooManyRedirects:
    # Tell the user their URL was bad and try a different one
except requests.exceptions.RequestException as e:
    # catastrophic error. bail.
    raise SystemExit(e)

Như Christian đã chỉ ra:

Nếu bạn muốn các lỗi http (ví dụ: Không được phép 401) nêu ra các ngoại lệ, bạn có thể gọi Response.raise_for_status. Điều đó sẽ đưa ra một HTTPError, nếu phản hồi là một lỗi http.

Một ví dụ:

try:
    r = requests.get('http://www.google.com/nothere')
    r.raise_for_status()
except requests.exceptions.HTTPError as err:
    raise SystemExit(err)

Sẽ in:

404 Client Error: Not Found for url: http://www.google.com/nothere

11
Câu trả lời rất tốt để xử lý các chi tiết cụ thể của thư viện yêu cầu và cũng có thể bắt ngoại lệ chung.
Brian Peterson

10
Lưu ý rằng do có lỗi trong thư viện urllib3, bạn cũng cần phải có socket.timeoutngoại lệ nếu bạn đang sử dụng thời gian chờ: github.com/kennethreitz/requests/issues/1236
jb.

15
Độc giả nhận xét trong tương lai: điều này đã được sửa trong Yêu cầu 2.9 (gói urllib3 1.13)
RazerM

14
Nếu bạn muốn các lỗi http (ví dụ: Không được phép 401) nêu ra các ngoại lệ, bạn có thể gọi Feedback.raise_for_status . Điều đó sẽ tăng HTTPError, nếu phản hồi là lỗi http.
Christian Long

5
Danh sách ngoại lệ trên trang web Yêu cầu chưa hoàn tất. Bạn có thể đọc danh sách đầy đủ ở đây .
Epoc

87

Một đề nghị bổ sung để được rõ ràng. Có vẻ như tốt nhất để đi từ cụ thể đến chung xuống các lỗi để nhận được lỗi mong muốn, vì vậy những lỗi cụ thể không được che dấu bởi lỗi chung.

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)

Http Error: 404 Client Error: Not Found for url: http://www.google.com/blahblah

đấu với

url='http://www.google.com/blahblah'

try:
    r = requests.get(url,timeout=3)
    r.raise_for_status()
except requests.exceptions.RequestException as err:
    print ("OOps: Something Else",err)
except requests.exceptions.HTTPError as errh:
    print ("Http Error:",errh)
except requests.exceptions.ConnectionError as errc:
    print ("Error Connecting:",errc)
except requests.exceptions.Timeout as errt:
    print ("Timeout Error:",errt)     

OOps: Something Else 404 Client Error: Not Found for url: http://www.google.com/blahblah

cú pháp hợp lệ này cho bài viết quá?
ScipioAfricanus

@ScipioAfricanus có.
andrea

10

Đối tượng ngoại lệ cũng chứa phản hồi ban đầu e.response, có thể hữu ích nếu cần xem phần lỗi trong phản hồi từ máy chủ. Ví dụ:

try:
    r = requests.post('somerestapi.com/post-here', data={'birthday': '9/9/3999'})
    r.raise_for_status()
except requests.exceptions.HTTPError as e:
    print (e.response.text)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.