2013-02-21 80 views
1

我有與服務器通信的C++應用程序。它將一些數據發佈到服務器,當我處理服務器故障的異常時,我得到了這個問題。當服務器出現問題時,我需要處理連接拋出的異常,並嘗試重新連接到服務器。我已經發布了以下相關的僞代碼:異常處理問題

try { 
    publisher->publishData(data); 
} catch (const ServerDownException& ex) { 
    //handle error, reconnect and create a new session 
} 

我已經是,處理此異常的時候,我需要再重新連接並創建一個會話的關注。再次創建會話的代碼可能會引發異常。因此,錯誤處理代碼將再次有一個嘗試 - 原來catch塊catch塊,如下:

try { 
    publisher->publishData(data); 
} catch (const ServerDownException& ex) { 
    publisher->initialize(); 
    publisher->openSocket(); 
    try { 
     publisher->createSession(); 
    } catch (const SessionException& tx) { 
     //session creation error 
    } 
    publisher->publishData(data);//after re-connecting, publish data again 
} 

我的問題是,是否確定有嵌套的嘗試 - 捕獲這樣嗎?否則這只是不好的設計?如果是這樣,那麼實現這一目標的最好方法是什麼?

PS .:我的代碼是C++,但我想這個問題是一般性的。 謝謝。

+0

很確定'publisher'應該知道它需要重新連接。 – 2013-02-21 10:01:38

+0

@PeterWood:請你多解釋一下? – Izza 2013-02-21 10:02:28

+1

我認爲彼得意味着這種情況不應有任何例外。如果發佈者不能發佈數據,它應該嘗試自己重新連接,而不會拋出異常並讓一些外部實體重新連接。但這取決於你的代碼,它只是太小而不能提供一些建議。 – ixSci 2013-02-21 10:17:53

回答

1

對象應自治。他們應該擁有正確行事所需的所有信息,並提供他們執行行動所需的對象。

CRCC lass R esponsibility C ollaboration。

應該告訴對象該做什麼,不被某些外部對象查詢和修改,以使其進入某種正確狀態。他們負責執行該行動。如果他們無法執行該行動,由於某種原因他們無法解決,他們應該拋出異常(或者至少以某種方式報告錯誤)。

如果您的發佈者無法發佈數據,則應該僅引發異常。不要像查詢那樣使用該異常:「哦,它斷開連接,需要重新連接。」

如果無法解決連接問題,然後它真的可以拋出一個PublishingException,而不是一個ServerDownSessionException

然後,您的代碼將不得不處理您無法發佈數據時要執行的操作。也許嘗試以不同的方式發佈,也許發送電子郵件給管理員。但不要嘗試重新連接,你已經知道發佈不起作用。

您可以嘗試再次撥打publishData。這就像一個政策:我們做什麼時發佈不起作用?該政策的正確位置取決於您的設計。

Publisher能夠滿足您與配置,如政策多少次嘗試重新連接,是否保留緩存,直到連接成功等,但那麼所有責任將在出版商屬於它不僅會如果無法實現,則拋出異常。

+0

這不是真的。我們對出版商一無所知。它可以是TCP套接字的封裝,在這種情況下它不應該是自治的。這一切都取決於抽象的程度。我們對此一無所知。 – ixSci 2013-02-21 10:38:20

+0

包裝TCP套接字,使其可以自治。 – 2013-02-21 10:50:35

+0

它將缺乏非自治套接字所具有的靈活性。這樣的低級別實體不應該向外部世界指示應該如何使用它。也許我不想重新連接功能。或者我想在這裏,不想在那裏。 – ixSci 2013-02-21 10:59:00

1

這是很難根據您發佈的唯一的代碼,使建議,但是,至少,我會做這樣的事情:

while(true){ 
    try { 
     publisher->publishData(data); 
     break; 
    } catch (const ServerDownException& ex) { 
    reconnect(publisher); 
    } 
} 

那裏重新連接由

publisher->initialize(); 
publisher->openSocket(); 
try { 
    publisher->createSession(); 
} catch (const SessionException& tx) { 
    //session creation error 
}