2013-04-12 46 views
1

我試圖捕獲greenlet中引發的異常。根據this tutorial,不幸的是'在Greenlet提出的例外,留在Greenlet'。在下面的代碼中,我有一個生成爬網小程序的同步方法。那些抓取greenlet引發了HTTPError異常,我需要在同步方法的主體中捕獲這個異常。根據例外情況,在同步方法中,我將設置Account對象的適當狀態。任何想法如何捕獲同步方法中的greenlet中引發的異常,以實現這一點?先謝謝你!在greenlets中引發異常

# this is standalone helper method 
def crawl(item): 
    try: 
     item.refresh_children(False) # THROWS HTTPError exception 
     greenlets = [gevent.spawn_link_exception(crawl, child) for child in item.children] 
     gevent.joinall(greenlets) 
    except HTTPError, e: 
     print e.message 
     raise e 
    except (JSONDecodeError, InvalidCredentialsException) as e: 
     print e.message 
     raise e 

# this is instance method of the Account class 
def sync(self): 
    "Sync search index with data from source" 
    try: 
     greenlets = [gevent.spawn_link_exception(crawl, item) for item in self.get_navigation()] 
     gevent.joinall(greenlets) 
     self.date_synced = datetime.datetime.now() 
     self.save() 
    except HTTPError, e: 
     if e.status_code == 401: 
      self.status = 'revoked' 
     else: 
      self.status = 'error' 
     self.save() 
    except LinkedFailed, e: 
     print e.message 
     exception_name = e.message.split()[-1] 
     if exception_name in ['HTTPError', 'JSONDecodeError']: 
      self.status = 'error' 
      self.save() 
     elif exception_name == 'InvalidCredentialsException': 
      self.status = 'revoked' 
      self.save() 

回答

0

Greenlets將保留爲greenlet或異常產生的函數的結果(如果引發了該結果)。您可以使用get方法獲得結果,或者重新提出異常。 因爲你似乎基於任何greenlets示數的同步方法也將結束看起來像要更改狀態:

def sync(self): 
    "Sync search index with data from source" 
    greenlets = [gevent.spawn_link_exception(crawl, item) for item in self.get_navigation()] 
    gevent.joinall(greenlets) 
    try: 
     results = [greenlet.get() for greenlet in greenlets] 
    except HTTPError, e: 
     if e.status_code == 401: 
      self.status = 'revoked' 
     else: 
      self.status = 'error' 
     self.save() 
    except LinkedFailed, e: 
     print e.message 
     exception_name = e.message.split()[-1] 
     if exception_name in ['HTTPError', 'JSONDecodeError']: 
      self.status = 'error' 
      self.save() 
     elif exception_name == 'InvalidCredentialsException': 
      self.status = 'revoked' 
      self.save() 

    self.date_synced = datetime.datetime.now() 
    self.save()