代码之家  ›  专栏  ›  技术社区  ›  ajthinking

在迭代器next中优雅地捕获python异常

  •  2
  • ajthinking  · 技术社区  · 6 年前

    我使用pygithub来抓取一些存储库,不过在迭代搜索页面时会遇到一些错误。

    def scrape_interval(self, interval):
        for repo_number, repo in self.search(interval):
            code...
    
    def search(self, interval):
        try:
            iterator = enumerate(self.github.search_repositories(query="Laravel created:" + interval))
        except:
            print.warning("Going to sleep for 1 hour. The search API hit the limit")
            time.sleep(3600)
            iterator = self.search(interval)
        return iterator
    

    如您所见,我在中创建迭代器时尝试捕获错误。 def search . 但是这个错误是在线的 for repo_number, repo in self.search(interval): 在某个时刻,迭代器得到下一个项?

    我的选择是什么使这些错误易于捕获?我最好避免将整个for循环包装在一个try子句中,而在迭代过程中对其进行管理。

    有关错误本身的参考:

    File "/Users/olofjondelius/Documents/Code/laravel-ai/src/examples/migration-analysis/../../GithubScraper.py", line 47, in scrape_interval
        for repo_number, repo in self.search(interval):
      File "/anaconda3/envs/laravel-ai/lib/python3.7/site-packages/github/PaginatedList.py", line 58, in _iter_
        newElements = self._grow()
      File "/anaconda3/envs/laravel-ai/lib/python3.7/site-packages/github/PaginatedList.py", line 70, in _grow
        newElements = self._fetchNextPage()
      File "/anaconda3/envs/laravel-ai/lib/python3.7/site-packages/github/PaginatedList.py", line 172, in _fetchNextPage
        headers=self.__headers
      File "/anaconda3/envs/laravel-ai/lib/python3.7/site-packages/github/Requester.py", line 185, in requestJsonAndCheck
        return self.__check(*self.requestJson(verb, url, parameters, headers, input, cnx))
      File "/anaconda3/envs/laravel-ai/lib/python3.7/site-packages/github/Requester.py", line 231, in requestJson
        return self.__requestEncode(cnx, verb, url, parameters, headers, input, encode)
      File "/anaconda3/envs/laravel-ai/lib/python3.7/site-packages/github/Requester.py", line 284, in __requestEncode
        status, responseHeaders, output = self.__requestRaw(cnx, verb, url, requestHeaders, encoded_input)
      File "/anaconda3/envs/laravel-ai/lib/python3.7/site-packages/github/Requester.py", line 309, in __requestRaw
        requestHeaders
      File "/anaconda3/envs/laravel-ai/lib/python3.7/http/client.py", line 1229, in request
        self._send_request(method, url, body, headers, encode_chunked)
      File "/anaconda3/envs/laravel-ai/lib/python3.7/http/client.py", line 1275, in _send_request
        self.endheaders(body, encode_chunked=encode_chunked)
      File "/anaconda3/envs/laravel-ai/lib/python3.7/http/client.py", line 1224, in endheaders
        self._send_output(message_body, encode_chunked=encode_chunked)
      File "/anaconda3/envs/laravel-ai/lib/python3.7/http/client.py", line 1016, in _send_output
        self.send(msg)
      File "/anaconda3/envs/laravel-ai/lib/python3.7/http/client.py", line 956, in send
        self.connect()
      File "/anaconda3/envs/laravel-ai/lib/python3.7/http/client.py", line 1384, in connect
        super().connect()
      File "/anaconda3/envs/laravel-ai/lib/python3.7/http/client.py", line 928, in connect
        (self.host,self.port), self.timeout, self.source_address)
      File "/anaconda3/envs/laravel-ai/lib/python3.7/socket.py", line 707, in create_connection
        for res in getaddrinfo(host, port, 0, SOCK_STREAM):
      File "/anaconda3/envs/laravel-ai/lib/python3.7/socket.py", line 748, in getaddrinfo
        for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
    socket.gaierror: [Errno 8] nodename nor servname provided, or not known
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Blckknght    6 年前

    听起来像是在迭代迭代器时引发了异常,而不是在创建它时。你当前 try except 块只捕获在调用时立即引发的异常 self.github.search_repositories 当你消耗结果的时候不会出现任何问题。

    为了解决这个问题,你可以 search 使发电机工作。这将允许您在拥有值的情况下生成值,但仍然捕获异常并根据需要重试。

    尝试如下操作:

    def search(self, interval):
        while True:
            try:
                it = enumerate(self.github.search_repositories(query="Laravel created:" + interval))
                yield from it
                return   # if we completed the yield from without an exception, we're done!
    
            except:  # you should probably limit this to catching a specific exception types
                print.warning("Going to sleep for 1 hour. The search API hit the limit")
                time.sleep(3600)
    

    正如我在评论中提到的,你可能应该改变 除了 语句到 except socket.gaierror 或者类似的东西,这样你就不会压抑 全部的 例外,但只有你期待的例外,一个延迟将为你解决。一些真正出乎意料的事情仍然应该被允许停止程序(因为它可能反映了代码中其他地方的错误)。

    推荐文章