如何在python WebDriver中处理偶发的BadStatusLine,CannotSendRequest错误

Jus*_*tin 5 python selenium webdriver jenkins selenium-webdriver

自从我们开始在jenkins中运行selenium UI测试以来,我们注意到在测试期间出现了一些小而烦人的错误.我们在看似随机的selenium动作(点击,退出,访问等)上得到BadStatusLine和CannotSendRequest错误.

它们通常看起来像:

  File "/usr/lib/python2.7/unittest/case.py", line 327, in run
    testMethod()
  File "/home/jenkins/workspace/Create and Upload Functional Testing/shapeways/test_suite/Portal/CreateAndUpload/TestUploadWhenNotLoggedIn_ExpectLoginModal.py", line 22, in runTest
    self.dw.visit(ShapewaysUrlBuilder.build_model_upload_url())
  File "/home/jenkins/workspace/Create and Upload Functional Testing/webdriver/webdriverwrapper/WebDriverWrapper.py", line 212, in visit
    return self.execute_and_handle_webdriver_exceptions(lambda: _visit(url))
  File "/home/jenkins/workspace/Create and Upload Functional Testing/webdriver/webdriverwrapper/WebDriverWrapper.py", line 887, in execute_and_handle_webdriver_exceptions
    return function_to_execute()
  File "/home/jenkins/workspace/Create and Upload Functional Testing/webdriver/webdriverwrapper/WebDriverWrapper.py", line 212, in <lambda>
    return self.execute_and_handle_webdriver_exceptions(lambda: _visit(url))
  File "/home/jenkins/workspace/Create and Upload Functional Testing/webdriver/webdriverwrapper/WebDriverWrapper.py", line 205, in _visit
    return self.driver.get(url)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 185, in get
    self.execute(Command.GET, {'url': url})
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 171, in execute
    response = self.command_executor.execute(driver_command, params)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/remote_connection.py", line 349, in execute
    return self._request(command_info[0], url, body=data)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/remote_connection.py", line 380, in _request
    resp = self._conn.getresponse()
  File "/usr/lib/python2.7/httplib.py", line 1030, in getresponse
    response.begin()
  File "/usr/lib/python2.7/httplib.py", line 407, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python2.7/httplib.py", line 371, in _read_status
    raise BadStatusLine(line)
Run Code Online (Sandbox Code Playgroud)

这个特例来自以下堆栈:

  • 硒== 2.44.0
  • 蟒蛇== 2.7.3
  • 火狐== 34.0
  • 詹金斯
  • xvfb(使用jenkins插件进行无头显示)

虽然我们已经看到这些错误一直出现在firefox/selenium的许多不同版本的排列中.

我运行了一个tcpdump来捕获BadStatusLine错误出现之前发送的实际请求并得到以下内容.

    POST /hub/session/ab64574a-4a17-447a-b2e8-5b0f5ed5e923/url HTTP/1.1 
    Host: 127.0.0.1:41246
    Accept-Encoding: identity Content-Length: 102
    Connection: keep-alive
    Content-type: application/json;charset="UTF-8"
    POST: /hub/session/ab64574a-4a17-447a-b2e8-5b0f5ed5e923/url
    Accept: application/json
    User-Agent: Python http auth

    {"url": "http://example.com/login", "sessionId": "ab64574a-4a17-447a-b2e8-5b0f5ed5e923"}
Run Code Online (Sandbox Code Playgroud)

响应返回0字节.所以BadStatusLine是由空响应引起的,这是有道理的.

问题是,为什么selenium的服务器会返回一个空响应.如果服务器死了,我们不会得到ConnectionError或那些沿线的东西吗?

Jus*_*tin 7

有一段时间,我没有责备,也不知道原因是什么.我终于能够通过运行来重现:

import requests
import json

while True:

  requests.post('http://127.0.0.1/hub/session/', data=json.dumps({"url": "http://example.com/login", "sessionId": "ab64574a-4a17-447a-b2e8-5b0f5ed5e923"}))
Run Code Online (Sandbox Code Playgroud)

当它运行时,我退出浏览器并得到BadStatusLine错误!当我再次尝试发出请求时,那就是我从任何死机服务器上看到的预期"ConnectionError".

所以,我怀疑发生的是当浏览器发送kill信号时,在关闭期间有一个短窗口,其中仍然会返回任何响应但是有0个字节.这就是为什么你会为基本相同的问题(浏览器死机)获得不同类型的异常.原来我们有一个cron在后台杀了我们的浏览器.