[英]Examples of error handling in Eiffel
我在Eiffel中找不到任何實質性的錯誤處理示例。 我只發現了一些瑣碎的示例,或者它們完全忽略了錯誤,或者將錯誤處理留給了讀者。 我很想知道在沒有異常的情況下錯誤如何在調用堆棧中傳播。 例如,我想知道發送網絡請求的應用程序如何將已在呼叫鏈中檢測到的網絡問題通知用戶。 這樣的事情。
-
編輯:我確實知道埃菲爾(錯誤和異常)中的錯誤處理的基礎。 但是,我找不到關於應用程序如何通過狀態處理錯誤的任何實質性示例。 故障狀態如何鏈接?
埃菲爾主張使用對象狀態而不是異常。 在這種情況下,客戶可能會弄清楚他們在發生錯誤時的期望並正確處理。 例如,
has_error: BOOLEAN
-- Has operation terminated with an error?
error_code: INTEGER
-- Last error code or `no_error'.
is_closed: BOOLEAN
-- Is connection closed?
response: detachable RESPONCE
-- Last response if `not has_error'.
send_request (data: REQUEST)
require
is_open: not is_closed
do
...
ensure
is_closed: is_closed implies (has_error and not connection.is_open)
is_successful: not has_error implies attached response
end
然后,客戶可以推斷供應商對象的狀態,並以可預測的方式繼續使用它:
interface.send_request (...)
if interface.is_closed then
... -- The connection is unusable and should be reestablished.
elseif interface.has_error then
... -- Inspect `interface.error_code', possibly trying to resend the request.
else
... -- Use `interface.response' to continue processing.
end
在存在例外的情況下,除了某些文檔之外,我們無法推斷出在何種情況下應采取的措施。 而且,它阻止使用自動工具,該工具可以輕松地檢查response
的使用在上面的代碼中是否完全正確。
如果錯誤在堆棧的最深處發生,則可以將異常機制與rescue
/ retry
一起使用。 但是,它可能會在底層網絡組件和用戶界面之間引入緊密耦合,這與網絡故障的詳細信息無關。 在最簡單的情況下,網絡類將使用適當的消息調用{EXCEPTIONS}.raise
。 更具體的方法是創建一個EXCEPTION
類型的對象(或后代),通過在其上調用set_description
設置相應的消息,並通過調用raise
引發異常。 可能會處理異常的用戶代碼如下所示。
local
is_retried: BOOLEAN
e: EXCEPTIONS
do
if is_retried then
-- There was an exception, handle it.
create e
if e.developer_exception_name ~ "This error" then
... -- Do something.
elseif e.developer_exception_name ~ "That error" then
... -- Do something else.
else
... -- Report yet another error.
end
else
... -- Some code that may fail with an exception.
end
rescue
if not is_retried then
is_retried := True
retry
end
end
編輯
處理嵌套錯誤的特定方法取決於應用程序設計,並且似乎與該語言無關。 可能的替代方法是:
( 如果使用異常機制,則不建議使用。 )在捕獲(較低級別)異常並對其進行處理以恢復類不變性之后,將引發新的異常,而不會取消前一個異常。 然后,查詢{EXCEPTION}.cause
可以(遞歸)用於訪問嵌套的異常對象。
可以使用類似於上一個的機制。 但是,除了創建新對象外,類還可以將對詳細信息的請求委派給較低級別的類。 例如,
class A feature has_error: BOOLEAN do Result := nested.has_error end error: STRING do Result := "Cannot complete operation X. Reason: " + nested.error end feature {NONE} nested: B end class B feature has_error: BOOLEAN do Result := nested.has_error end error: STRING do Result := "Cannot complete operation Y. Reason: " + nested.error end feature {NONE} nested: C end
可以使用記錄工具。 它們可以區分錯誤嚴重性,指定來源等。
class A feature do_something do nested.whatever if nested.has_error then log.error ("Cannot complete operation X.") end end has_error: BOOLEAN do Result := nested.has_error end feature {NONE} nested: B end class B feature whatever do nested.try_something if nested.has_error then -- An error has been reported by "nested". elseif something_else_goes_wrong then has_inner_error := True log.error ("Something goes wrong.") elseif has_minor_issues then log.warning ("Be careful.") end end has_error: BOOLEAN do Result := nested.has_error or has_inner_error end has_inner_error: BOOLEAN -- Some error that is not one of the errors reported by `nested'. feature {NONE} nested: C end
除了亞歷山大的回答外,有時使用異常也很方便。 在Eiffel中,我們通常不會捕獲它們(通常,類不變式已變得無效),但是對於某些應用程序,您只是不想處理錯誤。 如果有錯誤,您只需停止,然后依靠程序外部的重試即可。 使用這種方法的庫示例包括ecli和eposix。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.