2014-01-28 43 views
4

我的遺留代碼的簡單塊一個循環,通過節點的一些潛在的不良XML節點抓取的內坐着一個需要進行重構,因爲如預期它不工作:當Finally塊中的代碼拋出異常時會發生什麼?

Try 
    xmlFrag.LoadXml("<temproot>" & strXMLfragment & "</temproot>") 
    writer.WriteRaw(strXMLfragment) 
Catch ex As Exception 
    InvalidXML = True 
End Try 

什麼該塊是意思是要做的是檢查有效的xml,然後寫出xml出來。它實際上所做的是檢查無效的xml,然後將xml寫出只有如果它是有效的。所以它需要被修復才能按預期工作。

我在修復的第一次嘗試:

Try 
    xmlFrag.LoadXml("<temproot>" & strXMLfragment & "</temproot>") 
    'writer.WriteRaw(strXMLfragment) 
Catch ex As Exception 
    InvalidXML = True 
Finally 
    writer.WriteRaw(strXMLfragment) 
End Try 

這個工作對我的測試數據,但我擔心WriteRaw可能會引發對其他數據的異常。我還沒有找到關於什麼將導致WriteRaw拋出異常的決定性陳述,以及當Finally block中的代碼拋出異常時會發生什麼。

所以,我試圖重寫它像這樣:

Try 
    xmlFrag.LoadXml("<temproot>" & strXMLfragment & "</temproot>") 
Catch ex As Exception 
    InvalidXML = True 
End Try 
Try 
    writer.WriteRaw(strXMLfragment) 
Catch 
End Try 

坦率地說,它看起來醜陋的地獄。有沒有更優雅的方式來重構這個或者第一次嘗試是否合適?

+0

通常,您不應該將代碼放在Finally塊中,這可能會引發異常。很好的使用它會關閉數據庫連接,進行事務回滾等。在'Finally'塊中寫入文件可能會引發異常,與向外部服務等報告內容相同。 – Neolisk

回答

2

最後我想出了這個深刻古樸典雅的重構:

Try 
    writer.WriteRaw(strXMLfragment) 
    xmlFrag.LoadXml("<temproot>" & strXMLfragment & "</temproot>") 

Catch ex As Exception 
    InvalidXML = True 
End Try 

與執行第一,它會永遠寫出來的XML除非它拋出一個異常WriteRaw線。然後,LoadXml行可以測試有效性,而不會干擾將xml寫出。這樣InvalidXML標誌就按設計設置,不會有任何意外的異常。

3

當錯誤時拋出的Finally塊升起,什麼都不會發生:異常被傳播出來,像任何其他異常,並異常後,代碼在此finally塊將不會被執行。

如果strXMLfragmentnull或空字符串(或由於already running asynchronous operation),您的第一次嘗試將失敗。

所以,如果你真的想處理/吞下所有例外,你將不得不使用兩個Try塊。

+0

...或在Finally塊中創建Try塊。 –

3

爲了使它更清潔,你可能想拉你的第一個的try/catch到它自己的私有功能,使其可重複使用:

Private Function TryParseXml(ByVal xml as String) as Boolean 
    Try 
     XDocument.Parse(xml) 
     Return True 
    Catch ex As Exception 
     Return False 
    End Try 
End Function 

然後換你writer.WriteRaw調用在它自己的try/catch。

Dim myXml = "<temproot>" & strXMLfragment & "</temproot>" 
If TryParseXml(myXml) Then 
    xmlFrag.LoadXml(myXml) 
Else 
    Try 
     writer.WriteRaw(strXMLfragment) 
    Catch ex as Exception 
     ' handle exception 
    End Try 
End If 

是的,最終這是使用兩個Try/Catch塊。作爲確定Xml是否有效的唯一真正方法,沒有真正的解決方法是試圖解析它並等待它爆炸。

相關問題