2013-11-27 82 views
1

前一段時間我寫了一段代碼,燒瓶路線註銷從Web應用程序我工作的用戶來說,這看起來就像是:Python化的方式來處理錯誤和異常

@app.route('/logout') 
@login_required 
def logout(): 
    # lets get the user cookie, and if it exists, delete it 
    cookie = request.cookies.get('app_login') 
    response = make_response(redirect(url_for('login'))) 
    if cookie: 
     riak_bucket = riak_connect('sessions') 
     riak_bucket.get(cookie).delete() 
     response.delete_cookie('app_login', None) 
     return response 
    return response 

我做它的工作,當然是在工作,但現在我正在通過添加適當的錯誤處理來增強應用程序的可靠性,這是我之前在代碼中沒有做到的大規模任務。所以我偶然發現了這個路由函數,當我意識到我不知道如何以正確的方式做它時,我開始編寫它的新版本。這是我想出的:

@app.route('/logout') 
@login_required 
def logout(): 
    # why dont we call variables after what they are in specifics? 
    login_redirect = make_response(redirect(url_for('login'))) 
    try: 
     cookie = request.cookies.get('app_login') 
    except: 
     return login_redirect 
    # if we are here, the above try/except went good, right? 
    try: 
     # perhaps sessions_bucket should really be bucket_object? 
     # is it valid to chain try statements like that, or should they be 
     # tried separately one by one? 
     sessions_bucket = riak_connect('sessions') 
     sessions_bucket.get(cookie).delete() 
     login_redirect.delete_cookie('app_login', None) 
    except: 
     return login_redirect 
    # return redirect by default, just because it seems more secure 
    return login_redirect 

這也是它的工作,但仍然沒有看起來'正確'給我。所以,對於所有在編寫真python Python代碼方面都有豐富經驗的人來說,考慮到我喜歡用代碼很好地處理所有錯誤的代碼,可以被其他人閱讀,並且快速而且完美地完成它的工作情況下,而且在相當大的代碼庫的其餘部分):

  • 你怎麼呼喚你的變量,額外的特定的或一般:sessions_bucket VS riak_bucket VS bucket_object?
  • 你如何處理錯誤,通過嘗試/除了一個接一個,或通過嵌套一個嘗試/除了在另一個,或以任何其他方式?
  • 可以在一次嘗試中做多個事情嗎?除外,還是不行?
  • 也許是別的,這涉及到你的頭腦上面的代碼示例

提前感謝!

+0

坦率地說,隨着在線評論之外,您使用的嘗試 - 除了長相正確的我。當然,你可以從中學到很多東西,但從務實的角度來看,你的代碼很好。 – rdodev

+0

rdodev:第二個例子中的註釋是我對代碼是否正確的懷疑,並且意在在這裏回答。你是否也談到了第一個例子的評論,如果是的話,他們有什麼問題,什麼是更好的方法? – SpankMe

+2

我認爲捕捉所有異常通常是一個壞主意。 http://stackoverflow.com/questions/10594113/bad-idea-to-catch-all-exceptions-in-python –

回答

-1

我不知道確切的riak python API,所以我不知道拋出了什麼異常。另一方面,Web應用程序應該如何在不同的錯誤條件下運行?是否通知用戶?

  • 變量名稱:我更喜歡泛型。如果更改實現(例如會話存儲),則不必更改變量名稱。
  • 例外:取決於所需的行爲。如果您想從錯誤中恢復,請嘗試/除了一個接一個。 (一般來說,線性代碼更簡單。)如果你不能從錯誤中恢復,我會發現一個更大的try子句和幾個異常子句是非常可以接受的。
  • 對我來說,一次嘗試/除了做幾件事情可以。如果try/except子句太多,代碼的可讀性就會降低。
  • 更多內容:伐木。 logging.exception將記錄回溯,以便您可以知道錯誤出現的位置。

一些建議:

import logging 
log = loggin.getLogger(__name__) 

@app.route('/logout') 
@login_required 
def logout(): 
    login_redirect = make_response(redirect(url_for('login'))) 
    try: 
     sessionid = request.cookies.get('app_login', None) 
    except AttributeError: 
     sessionid = None 
     log.error("Improperly configured") 
    if sessionid: 
     try: 
      session_store = riak_connect('sessions') 
      session = session_store.get(sessionid) 
      if session: 
       session.delete() 
      login_redirect.delete_cookie('app_login', None) 
     except IOError: # what errors appear when connect fails? 
      log.exception("during logout") 
    return login_redirect 
+0

我不認爲它是一個很好的建議,因爲它不能解決任何問題,也不能回答我的問題。除此之外,第二個除了catch之外,你都說刪除會話信息有問題,而try可能會在第一行失敗,那就是數據庫連接 - 並不完全是刪除cookie的問題。 – SpankMe

+0

我試圖改進以下幾點:1.使用回溯記錄異常,以便準確知道代碼失敗的位置。我試圖保持相同的行爲,不向用戶通知錯誤。 2.變量命名:如果您將會話存儲移到其他沒有「存儲分區」的其他位置,那麼您的代碼仍然可以。桶的使用是一個實現細節。 3.減少出口點。我會盡力改進答案。 – erny